Copyright: ® Kirk Wolak


Delphi Knowledge Base
The Delphi Knowledge Base

Disclaimer**

Frequently Asked Questions

Misc/Tips

IDE

BDE

Client/Server

OOP

C/C++

Visual Bascom [sic]

Installing Delphi

Tables*

Bugs*

Updates Available*

Unsolved Questions*

Web Sites/FTP Sites*

Books/Magazines*

Delphi Seminars by Grumpfish

Submitting to The DKBS**

Credits**


Disclaimer**

Standard Disclaimer


Frequently Asked Questions

What is the purpose of this FAQ?

How can I get the latest version of this FAQ?

Is this FAQ copyrighted?

What is Delphi?

What versions of Delphi are there?

How much disk space, memory, etc., do I need to run Delphi?

How tough is it to learn Delphi?

What's the difference between Delphi Desktop and Delphi Client/Server?

Can you write multi-user database applications in Delphi Desktop?

What is the history of Delphi?

Where can I get a copy of Delphi?

How can I contact Borland?

What known bugs exist in Delphi?

Does anyone publish a Delphi magazine or journal?

Where can I find sample source code and utilities for Delphi?

What operating systems does Delphi support?

What source management tools are compatible with Delphi?

Can I use DLLs developed in C or C++ from Delphi?

Can I make calls to Delphi code from C or C++?

What third-party packages are specifically known to work (or not work)

How do I get access to a database from Delphi?

Does Delphi support the <mumble> back-end?

What data-aware controls come with Delphi?

Can I use the ODBC drivers that I got with <mumble>?

What about data-aware VBXes?

How do I write a "change password" function for a Paradox table?

Why do I get errors when I call the Add method for a TFieldDefs?

What is the procedure for connecting Delphi to an MS Access database?

How can I manipulate data programmatically?

What target formats can I create using Delphi?

I built a small test project. What are all these files?

How can I yield the CPU to other tasks, like "DoEvents" in VB?

Why do I get compile errors accessing the Sender object in events?

Are there any tools to help me migrate my applications to Delphi?

What's the Delphi equivalent of Visual Basic control arrays?

How do I close a modal form? For that matter, what's the best way to

Are there commercial applications developed in Delphi?

Do I have to know a lot about the Windows API to use Delphi?

Do I have to understand object oriented programming to use Delphi?

How does Delphi's exception handling work?

Does Delphi use Pascal or C style strings?

How does Delphi handle Windows callbacks?

How does Run-Time Type Information (RTTI) work?

I'm creating a toolbar, but I have icons, not bitmaps. Help!

When I use the Glyph property, how do I know which color is transparent?

How can I make my Delphi application respond to Windows messages?

How can I allocate blocks of memory larger than 64k?

Is it possible to write a Windows screen saver in Delphi?

I'm trying to call <mumble> from Delphi and it GPFs.  What's up?

How can I add pages to a TTabbedNotebook at run-time?

I'm painting complex graphics.  How can I speed up redrawing?

How can I have MDI child windows?

How do I write a global error handler?

Why do I get exception messages even though I'm in protected code?

I've added code to my OnKeyPress event that traps Enter keys, but ...

I want to modify a component's properties at run-time, but ...

Is there anything in Delphi similar to the VB "setup wizard?"

What files am I allowed to redistribute with my applications?

What other files do I need to send with a Delphi EXE

I want to distribute a database application, but I don't want to ...

Several general questions

Delphi's Directories

What is Delphi?

Can Delphi create VCL's for itself?

Delphi licensing ambiguity?

ListBox question

Flash Message Form

How to make Delphi interruptable

Minimum Requirements - RAM

Delphi's EXE's are HUGE!!

64K data segment limit in Delphi?

API calls?

TBlobField and the meaning of life...

Using TrueGridPro

One form calls another

193k file??? HELP!

Accessing MS-DOS Environment Variables from Delphi?

How to share variables between 2 units in delphi. Help.

Desktop Version vs. Client Server

Using DOSERROR

Compiling DLLs

Reading and displaying a line from a file

DELPHI beeps at me

Turbo Pascal and Delphi

Bitwise Operations and Links to a C++ module

DOS and Win execs in one .exe file

Control arrays in Delphi?

Async Professional for Windows

What is Delphi?

Is delphi a repackage of TP7 for Windows?

Delphi MessageBox and variable?

Delphi hates PCTools for Windows 2.0

Winsock via DELPHI

What are and how do I use pointers?

What are interrupts?

Delphi Screen Parameters

ExitWindows(0, wrongcodes)

How do I run my app minimized??

Current directory/drive ?

Properties by name?

10 REASONS to use Delphi

Formless delphi application

Normalized or Iconized?

How to create Delphi TForm.Minimize

Delphi: version control program?

Delphi-Mouse movement over control

Formated Memos in Delphi

Beep for me baby!!

Tab contols missing from VCL Source?

SQL: SELECT COUNT

Can we use TDW from BP7 with Delphi?

Delphi & Bound Data Controls

Playing .wavs

Autofilling a TBListBox

Error creating process?

ScrollBox1.HorzScrollBar changed?

Delphi and Files

Problem passing dates to report

Setting Checked state on TCheckBox

Resize Forms

Delphi for OS/2, Mac

MessageDlg & Dialogs UNIT

Sparse unit removed in release version

Memory Allocaton and Freeing

How to make DropDownCombo in StringGrid or other Grid?

Declaring APIs in Delphi

How do I forfeit control?

Dates and times in a messagebox

"SelText: string;

Pointers and Components

A Winexec question

How to use tabs in TListBox strings?

Some General Questions

TStringList in Delphi

Displaying messages via panel

Delphi Documentation Errata

Help with Case statement in Object Pascal

How to display an array of strings?

How to include a "crystal report" in a Dephi app

TMemo and TEdit

Creating components at RUN TIME?

Crt & Form Problem.

Sets

Visual Solutions

How do I close an MDI Child during runtime in Delphi?


Misc/Tips

Multiline Lines

Array in my own component, How ?

Useful Delphi Unit

Tab key in KeyDown event?

TStrings Property Editor(???)

Running or Designing, how do I tell?

TOutline owner-draw problem

Using Temporary VB strings from within Delphi

Property TStrings gives error..

Telling IDE of changes & mouse events in design mode

How to add a Splash Screen to my app ??

child forms w/o MDI?

Height of Comboboxes *

Sorted TLists?

Transparent Bitmaps-SOLUTION

TOutline - OnDrawItem isn't being called

Can Someone Explain the TWriter/TReader

List of Constants?

Major crash through Power shortage

Blocking Default Behavior?

Win API

Delphi Libraries

GREAT SECRET of Delphi

Executing Another Windows App

Can you delay the OnHint Event?

Errorlevel final version

.pas to printer??

Tip A-#1: using .hlp

Graphics Unit

Stretching 256 color bitmaps

Stretching 256 color bitmaps

Printing in cm's (inches)?

Run Multiple Delphi.exe

Compare two blocks of code

Image Editor Reboots Computer

Help moving Title-barless Form

Preventing User from Maximizing Forms

Beware infinite event loops!

FORMS - DRAGGING WITHOUT CLICKING THE CAPTION BAR

MAKING DELPHI APPS SHOW MINIMIZED

HOW TO MATCH FILE DATE/TIME STAMPS

USING ONHINT EVENTS AMONG MULTIPLE FORMS

MAKING THE ENTER KEY WORK LIKE A TAB IN A TDBGRID

MOVING TO A TAB BY NAME ON A TABSET

ENCRYPTING STRINGS

UNDO IN A MEMO FIELD

GETTING LINE NUMBER IN A MEMO

PRINTING CONTENTS OF A TMEMO OR TLISTBOX

EXTRACTING A BITMAP FROM A BLOB FIELD

CONTROL FONT STYLES

HOW TO HANDLE TEXT DRAWING IN A TDBGRID

SEARCHING YOUR APPLICATION'S HELP FILE

MANAGING DISK VOLUME LABELS

COPYING FILES

POINTER ARITHMETIC

FORM DISPLAY WITH DIFFERENT SCREEN RESOLUTIONS

HOW TO TERMINATE ALL RUNNING APPLICATIONS

HOW TO CHECK IF A DRIVE IS READY

BIT-WISE MANIPULATION

HOW TO KEEP APPS ICONIZED

ADDING TIME AND DATE STAMP TO MEMOS

RECURSIVELY REMOVING FILES AND SUBDIRECTORIES

CHARTFX EXAMPLE

GETTING A DEVICE CONTEXT FOR A CONTROL

DISABLING NAVIGATOR BUTTONS

DBGRID THAT SHOWS IMAGES

TRANSPARENT WINDOW

GETWINDOWSDIRECTORY

CONFIGURING AN ODBC DRIVER AND ALIAS FOR DELPHI

CONNECTING TO ACCESS 2.0 DATABASES VIA ODBC

CREATING A SYSTEM MODAL APPLICATION

ASSERTIONS IN DELPHI

DUPLICATING THE ATAN2 FUNCTION IN DELPHI

GETTING DIMENSIONS FROM .AVI FILES

USING CANVAS IN USER-DEFINED COMPONENTS

DETERMINING CD TRACK WITH TMEDIAPLAYER

ACCESSING OTHER COMPONENTS FROM A BASE COMPONENT

COLOR TO STRING CONVERSION FUNCTIONS

DETECTING A PENTIUM PROCESSOR

DISPLAYING IMAGES WITH DBGRID

EXTENDING DBGRID

DELAY PROCEDURE

ACCESSING DOS ENVIRONMENT DATA FROM DELPHI

CREATING A RESIZABLE (ELASTIC) PANEL

TRAPPING WM_ENDSESSION MESSAGE IN DELPHI

RESTARTING WINDOWS

READING AND WRITING DATA TO/FROM FILES

TRIMMING SPACES FROM STRINGS

CONTROLLING FORM MAXIMIZATION

REMOVING TITLE BAR FROM MDI CHILD FORM

DETERMINING CURSOR POSITION WITHIN EDIT FIELD

ASSIGNING ONCLICK EVENTS FOR MENU ITEMS CREATED AT RUN-TIME

DRAWING TO A METAFILE

HOW TO FORM A DDE LINK WITH A NETSCAPE WEB BROWSER

PREVENTING MULTIPLE INSTANCES OF SAME APPLICATION

WRITING A SCREEN SAVER IN DELPHI

HOW TO AUTOMATE MEMO OR WINDOW SCROLLING

SETTING BOUNDARIES FOR NEWLY CREATED CONTROLS

SETTING SYSTEM DATE AND TIME

COPYING FILES USING LZEXPAND

EXPANDING A PATH TO A TOUTLINENODE REFERENCED BY INDEX

HIDING REPORTSMITH RUN-TIME ENGINE LOGO

MakeProcInstance

MakeProcInstance

E-Mail

CALLBACKS in Delphi - Help?

Knowing when a task closes?

Which runs faster?

Foward declaring classes???

Close a help window with delphi code ??

Is there any equivalent of TPW's Collections in Delphi?

What is the function to cause Delphi To yield execution

Launching NetScape from Delphi

System Menu while Minimized

Can't access Delphi DLL from VB

Controlling Glyph transparent color on SpeedButton

Win95 Taskbar Icon for each form

Repaint Icon while App is Minimized?

Printer positioning


IDE

Invalid Indirect Reference

SystemMenu Question

Delphi: edit source code in break mode?

DELPHI merging menus in MDI app

Project .DSM file?

Delphi Easter Egg.

Debuging DLL not supported

EGPFault on .DPR

TROUBLE RUNNING DELPHI PROGRAMS FROM DELPHI


BDE

BDE error codes and descriptions

Delphi-DBF-Index?

Paradox Table over a Network

Delphi and Btrieve

Access 2.0 db and Delphi

Can Delphi read Foxpro dbs

Problem with Delphi exception EDBEditError

DB format to use?

dBASEwin->delphi-Index (string) problems

DELPHI & Borland Database Engine

Can Delphi Use Paradox Engine?

Can I ship only part of the BDE?

Creating InterBase Tables using the Desktop

Two forms accessing the same table

Best way to set range, filter...

Anyone got an interbase app working??

SQL and Paradox

Delphi-Paradox: table password

Delphi-Access

Query a Query

Delphi --> MS SQL Server using ODBC ???

DELPHI -> Addindex broken?

Creating Simple Databases

Delphi->dBASE complex index again

Visible sort & restricting records?

TQuery Question

DB Controls: Scrolling and Which Record

DELPHI Dislikes Changing Database Field Size

Query and live data sets (Views)

Search the Data Base

How to detect an empty data set?

"Error creating cursor handle"

Delphi: help on Unit, TQuery, OOP database?

Delphi Heterogenous SQL Select

dbase files on a LAN and DELPHI

DELPHI: read/write 1 rec. not on screen!

What data-aware controls come w/ it?

Indexed Paradox Tables Database in Delphi

Delphi Database Examples

Stopping inserting in Delphi TDBGrids

Error 70: Unit Version Mismatch- why?

Some Delphi Questions

BDE and other data base types

Delphi DB Aware List Box

HOW TO CIRCUMVENT THE "INDEX NOT FOUND" EXCEPTION

CREATING DATABASE ALIASES IN CODE

CREATING & DELETING TFIELDS AT RUN-TIME

ITERATING THROUGH THE FIELDS OF A TABLE

GETTING A QUERY'S MEMO FIELD AS A STRING

LOADING BITMAPS INTO DBASE/PARADOX BLOB FIELDS

EXTRACTING A BITMAP FROM A BLOB FIELD

SEARCHING THROUGH QUERY RESULT SETS

EXTRACTING INDEX DATA FROM A TABLE

REDISTRIBUTING THE BORLAND DATABASE ENGINE (BDE)

CASCADING DELETES WITH PARADOX REFERENTIAL INTEGRITY

DBASE EXPRESSION INDEXES: A PRIMER

REMOVING THE VERTICAL SCROLLBAR FROM A TDBGRID

INTERBASE BLOB FIELDS: A PRIMER

USING THE ASCII DRIVER WITH COMMA-DELIMITED FILES

DETERMINING RECORD NUMBER IN A DBASE TABLE

REDISTRIBUTING THE BORLAND DATABASE ENGINE (BDE), PART 2

[Q] about a caption (simple question)


Client/Server

Cost of Client Server Edition


OOP

Referencing SENDER object in Delphi

Delphi and WM_xxx Handling.

Delphi Pascal Language

Can Delphi build OCXs?

OLE Automation in DELPHI?

Creating new instances

Creating controls on TTabbedNotebook

ActiveMDIChild and ChildWin

Why call Destructor??

Exception handling?

Object Dereferencing Problem

Constructor Question

Objects and classes

Constructor calling

Overriding Create?

Multiple Inheritance In Delphi

Missing multiple inheritance ... what instead?

Detecting previous Instance

Free method causes GPF?

SetWindowsPos....

Class Allocation

Pointers and Components

How does one clone a component


C/C++

Calling C DLL from Delphi


Visual Bascom [sic]

Equivalent of VB DoEvents

Equivalent of VB DoEvents

Delphi and VB Professional Toolkit v1

Delphi's eqiv to VB's Setup Wizard

Delphi Equivlant of SendKey()

VB3 to Delphi converter?

Equiv for VB's Form.Print?

'Unknown Identifier' error on second form?

VB ---> DELPHI porting???

Delphi equivalent of VB control arrays


Installing Delphi

Delphi mystery - Exception at Launch

Installing form CD Error

Run Delphi from the CD!

Delphi gives 'Out of System Resources' Error

Delphi & Windows Resources Problem

Delphi Local - Accesing Paradox on the LAN

Delphi & Windows Resources Problem


Tables*

Run-Time Errors


Bugs*

TextToFloat bug when called from a dll

Bounds-Checker found memory leaks in Delphi programs!

Finally, at last at last!

Minimising Child Window

IDE BUG ?

Another Delphi IDE BUG

Image Editor Bug?

DELPHI - Problem with OwnerDrawn TOutline

TOutLine OnDraw Event

TStringList.Find doesn't work!

OFFICIAL BUG (Ctl32v2.dll)


Updates Available*

Delphi process threads


Unsolved Questions*

Clock.exe GPF

Delphi components broken in Warp

How to derive class that accepts data on creation?

Creating DB Tables in delphi

StrAlloc anomaly?

Mousecursor changing wierd....

DBE config for Access Tables

Placing an Icon on a TBitBtn


Web Sites/FTP Sites*

Grumpfish FTP Directory

Various Web Sites

Distributing programs

Multi-line Hints?

INSTALLATION UTILITY

ReportSmith discussions

Report Smith a nightmare !!!!!!!!!!

WWW-Sites

New WWW URL - Boris Ingram's Home Page

Delphi ftp sites ?

Does a freeware\shareware zip compression algorithm Exist

Intel 3DR

ANNOUNCE: Delphi Bug List

Delphi Shareware CD-ROM

Is there a FAQ for delphi?

Delphi on TP Page

Q: any components ?

ANNOUNCE:   New Delphi WWW Site

Is there a Delphi knowledge base???

Delphi FAQ

Component Development Book

Grumpfish Web Site

Compression with Delphi

Expression Evaluator Source?


Books/Magazines*

What are some good books about Delphi?

Delphi Unleashed

Delphi By Example

Instant Delphi Programming

The Tao Of Objects

Delphi Programming Explorer

Delphi Programming For Dummies

Delphi Developer's Guide

Delphi: A Developer's Guide

Delphi language reference

Delphi Documentation

WWW-based magazine "The Delphi Connection"


Delphi Seminars by Grumpfish

Delphi Seminars Series


Submitting to The DKBS**

How to Send Articles to The DKBS

Topic Names & Abbreviations


Credits**

The Developers of the Delphi KBS

Lloyd, and Lloyds Help File

Mike Orriss, Dtopics

ZAC Catalog, Delphi only Tools


Standard Disclaimer

This file contains information.  The accuracy or correctness of this information is not quarantined in any way, manner, or form.  Use what you find in here with care.  We assume no responsibility whatsoever for the information contained herein.  Furthermore, the information was gathered from public sources.  Whatever information is used is assumed to be used either within the guidelines of Fair Use, or with the accepted consent of the originator of the information via the fact that it was posted for public consumption.

Finally, any sentiments or statements are those of the  contributor, and not those of Kirk Wolak, CBF Systems, Inc. or any subsidiary thereof.


What is the purpose of this FAQ?

#00000001.FAQ	From FAQ

   This FAQ is intended to answer some questions about the new development

   environment from Borland International called Delphi. Information in this

   document is not guaranteed to be correct. Use it at your own risk.

   This is not really a FAQ in the purist sense of the term, because some of

   the questions answered here are not really very frequently asked at all.


How can I get the latest version of this FAQ?

#00000002.FAQ	From FAQ

   This FAQ is posted to comp.lang.pascal approximately monthly. If it's

   expired on your news server, you can get it via anonymous ftp to

   ftp.mhn.org as /pub/delphi.faq; or you can get it from WWW as

   <http://www.mhn.org/delphi.faq>.


Is this FAQ copyrighted?

#00000003.FAQ	From FAQ

   Yes. A work is copyrighted by the act of publication. But you are hereby

   authorized to do whatever you want, however you want. I request that if you

   distribute all or part of this FAQ, you also distribute the 0 section.

   Also, this authorization applies to *this version* only. I reserve the

   right to apply whatever copyright restrictions I see fit to future

   versions.

   THIS IS FROM THE TEXT BASED FAQ...  IT DOES NOT APPLY TO THE KNOWLEDGE

   BASE YOU ARE VIEWING IT IN!!!!


Frequently Asked Questions - What is Delphi?
What is Delphi?

#00000004.FAQ	From FAQ

   Delphi is a product of Borland International. It is a native code compiler

   that runs under Windows 3.1 and provides visual programming tools somewhat

   similar to those found in Microsoft Visual Basic 3.0. The underlying

   language is Object Pascal, which is an extension of the object-oriented

   Pascal found in Turbo/Borland Pascal starting with version 5.5.


What versions of Delphi are there?

#00000005.FAQ	From FAQ

   Delphi has been available in beta-test for many months now, and Borland has

   also given away a large number of "prerelease" copies. As far as the

   official release is concerned, though, there are two packages: Delphi

   (sometimes referred to as Delphi Desktop) and Delphi Client/Server. Both

   are version 1.0.


How much disk space, memory, etc., do I need to run Delphi?

#00000006.FAQ	From FAQ

   The minimum installation of Delphi takes about 30Mb, and the full install

   takes 80Mb. In order to run it well, you'll need a 486 with a minimum of

   8Mb of RAM, though I personally wouldn't try to run it in less than about

   12Mb. I use a 486DX2/66 at home and a Pentium-90 at work, and to be honest,

   there's not much difference between them--Delphi's compiles are so fast

   that the CPU is really not a bottleneck.


How tough is it to learn Delphi?

#00000007.FAQ	From FAQ

   If you're lucky, you already have lots of experience with both Object

   Pascal (or, as it used to be called, Borland Pascal With Objects--

   essentially, Turbo Pascal v5.5 or later) and with Visual Basic. If you fit

   this description, then Delphi will be a breeze for you.

   Okay, now for everyone else. In order to make full use of the Delphi

   environment, you have to know Pascal, you have to have some grasp of object

   orientation, and you have to understand event-driven programming. Once

   you're over those three hurdles, you've pretty much got it. See section 5

   for more information.

   On the other hand, most people don't need to make "full" use of the

   environment. If you just want to pull a simple application together that

   doesn't do anything too fancy, Delphi shouldn't be any harder to learn than

   VB--it's just that there's a whole lot more you *can* do in Delphi, which

   will make you feel more lost than you really are.


What's the difference between Delphi Desktop and Delphi Client/Server?

#00000008.FAQ	From FAQ

   Delphi Client/Server includes everything from Delphi Desktop, plus the

   following:

      - SQL-Links 2.5, which includes native client drivers for Oracle,

   Sybase, Informix, and InterBase, and includes full royalty-free

   redistribution rights to those drivers, and which costs $995 if bought

   separately;

      - The Local InterBase Deployment Kit, $495 (*);

      - ReportSmith/SQL, $300 (**);

      - "Team development support" -- interoperation with PVCS (obviously,

   this is no use to you if you don't own PVCS), not available separately;

      - The visual query builder, which creates SQL statements for you, also

   not available separately;

      - The VCL source code, which is available separately for $100.

   (*) Local InterBase is a single-user SQL database engine. The version

   included in Delphi Desktop is intended to be used by developers who want to

   write SQL applications that can be seamlessly migrated to client/server

   environments, but without buying their own (expensive) server platform.

   However, Delphi Desktop does not include redistribution rights. If you want

   to distribute a single-user application that uses Local InterBase, you have

   to pay extra for the deployment kit.

   (**) The version of ReportSmith bundled with Delphi Desktop specifically

   detects and excludes any server-based ODBC drivers from its list of

   acceptable connections. Yes, you heard that right. Even though you've got

   third-party ODBC drivers, and even though you can talk to these drivers

   just fine from the Delphi environment, ReportSmith still won't work. If you

   want to do this without buying Delphi Client/Server, you can buy

   ReportSmith/SQL separately for $300. As an alternative, if you happen to

   already own a copy of Visual Basic, you can use the Crystal Reports VBX

   just fine from within Delphi.


Can you write multi-user database applications in Delphi Desktop?

#00000009.FAQ	From FAQ

   Using regular, non-client/server Delphi, I have developed an application

   that talks to a Sybase server using ODBC drivers. I didn't have to go to

   any serious trouble getting it to work, and data access speed is quite

   acceptable, better than it was under Visual Basic.

   Steven Lamotte <slamotte@jenex.mb.ca> says: "I think the benefits of the

   native SQL drivers relate mostly to speed. It may be true that ODBC allows

   you to do most everything a server permits, but your SQL commands still

   have to be processed by ODBC. I once wrote a program to compare Sybase SQL

   Server access with C++ using ODBC and using OpenClient (the native SQL

   interface for SQL Server) and the results were that the native interface

   version performed several times better than ODBC."


What is the history of Delphi?

#00000010.FAQ	From FAQ

   Delphi is the descendant of Turbo Pascal, which was first released in 1983

   for the CP/M operating system. Turbo Pascal was ported to MS-DOS in early

   1984. During the early history of the IBM PC, Turbo Pascal was arguably the

   most popular language for serious development work--mostly because it was a

   real compiler, including the program editor and everything, that cost

   $19.95 and would run on a 128k machine. Borland introduced Turbo Pascal for

   Windows in 1990. The latest release of Borland Pascal (as it is now

   called), not including Delphi, was version 7.0 in late 1992.

   Delphi had an unusually long deveopment cycle--somewhere between 18 months

   and two years, depending on who you talk to. Various beta-test and

   prerelease copies have been circulated, including several hundred "early

   experience" copies which were given away at the trade show Software

   Development '95. Delphi was officially announced in the US on Feb. 14,

   1995, and the first release-level copies were shipped on Feb. 28.


Where can I get a copy of Delphi?

#00000011.FAQ	From FAQ

   If you are in the US, You can order Delphi Desktop on CD-ROM for an

   introductory price of $199 by calling Borland's credit card order desk at

   1-800-331-0877. If you are a registered user of any version of Turbo Pascal

   or Borland Pascal, you qualify for an upgrade price of $149, and you can

   also buy the Visual Component Library Source Code for $49. The introductory

   pricing is good through approximately May 15, 1995; after that, the price

   will be raised to $495. Delphi Client/Server is $1999.

   Of course, if you buy through a reseller, you will probably pay less.

   According to Borland, "Delphi is available through the following US

   resellers: CompUSA, Best Buy, Elek-Tek, Computer City, Babbages, Software

   Etc., Fry's, Electronics Boutique, Corporate Software, ASAP Software

   Express, Egghead Software, Softmart, Software Spectrum, CDW, PC Connection,

   Programmer's Paradise, Programmer's Warehouse, ProVantage Shop, and Micro

   Warehouse."

   Note that you do NOT have to go through Borland directly to get the upgrade

   price. When you buy a copy of Delphi at the discounted retail price (US

   street prices are $179-$189), the box contains a coupon for the $50

   discount if you mail in a serial number for Turbo or Borland Pascal. You

   have to send in a photocopy of your install disk, or the original first

   page of your manual.

   Borland also maintains list prices in several other currencies through

   their various international offices. In addition, distributors sell Borland

   products across the globe. I do not currently have any verified information

   about non-U.S. pricing for Delphi; check with the closest Borland office or

   with your distributor or reseller.

     9 What if I don't have a CD-ROM drive?

   Borland will ship Delphi on 3.5" floppy diskettes, but they charge extra

   for them. The resellers I have spoken to only carry the CD-ROM version

   because they don't want to have to stock two different items. I got my copy

   on CD, but the CD has directories on it called DISK1 through DISK15, so I

   assume it would be 15 diskettes if you got it that way. If you don't get

   the CD, you won't get the stuff they use to fill up space on the CD, like

   an AVI file of an animated spinning Delphi logo.


How can I contact Borland?

#00000012.FAQ	From FAQ

   If you have the necessary access, you can get information directly from

   Borland at their web site, <http://www.borland.com>, or at their anonymous

   ftp site, ftp.borland.com. If this doesn't work for you, here is a list of

   their (voice) telephone numbers:

   Australia                                       (61) 2 911 1000

   Belgium/Luxembourg                              (32) 2 4610 448

   Brazil                                          (55) 11 851 5326

   Canada                                          (416) 229 6000

   Chile                                           (56) 2 233 7113

   Denmark, Norway                                 (45) 22 62 89 00

   Eastern Europe, Mediterranean, Russia, Middle   (33) 1 41 23 11 00

   East

   France                                          (33) 1 41 23 11 00

   Germany, Austria, Switzerland                   (49) 61 03 9790

   Asian Headquarters/Hong Kong                    (852) 540 4380

   Italy                                           (39) 2 26 91 51

   Japan                                           (81) 3 5350 9370

   Korea                                           (82) 2 551 2795

   Latin America Headquarters                      (408) 431 1074

   Malaysia                                        (60) 3 230 2618

   Netherlands                                     (31) 020 540 5400

   Singapore                                       (65) 339 8122

   Spain                                           (34) 1 650 7250

   Sweden, Finland                                 (46) 8 799 20 00

   Taiwan                                          (886) 2 718 66 27

   United Kingdom                                  (44) 734 320 022

   USA                                             (408) 431 1000

     11 What technical support do I get with Delphi?

   You get access to the "up and running" line, which will only answer

   questions related to installing Delphi and getting it to run on your

   machine. Also, it is worth noting that the hold times on this line are very

   long indeed--don't expect to talk to anyone without waiting 20 to 30

   minutes.

   In order to get what borland calls "consultative" tech support (I.E.

   someone with whom you can discuss reasons why a program is not working),

   you have to pay $2/minute. You can call (900) 555-1015 and have the charges

   put on your phone bill, or else (800) 330-3372 and use a credit card. I

   have called twice, and they couldn't answer my question either time;

   however, they didn't charge me for the calls.


What known bugs exist in Delphi?

#00000013.FAQ	From FAQ

   A complete listing is beyond the scope of this FAQ; however, if you have

   WWW access, you can look at:

   <http://www.cybernetics.net/users/bstowers/delphi-bugs.html>.

   1.   I just bought Delphi.  Where are the language and library reference

   manuals?

   They don't ship those manuals with Delphi because of their size.  The

   component library reference is over 1000 pages.  You can get all this

   information from the on-line help, or you can ftp the manuals from Borland

   in Acrobat format, or you can order the actual books for an additional

   charge.

   ------------------------------

   2. Delphi Resources.


Does anyone publish a Delphi magazine or journal?

#00000015.FAQ	From FAQ

   The following magazines are listed on the Borland WWW server:

   Delphi Developer, 12 issues/$99, Pinnacle Publishing (206) 251-1900

   Delphi Informant, 12 issues/$49, Delphi Informant (916) 686-6610

   Inside Delphi, 12 issues/$79, Cobb Group (502) 493-3200

   The Delphi Magazine, 6 issues/???, The Delphi Magazine +44 0 181 460 0650


Where can I find sample source code and utilities for Delphi?

#00000016.FAQ	From FAQ

   Borland seems to use CompuServe as their primary on-line service.  There

   are quite a lot of Delphi files in Borland's forum there.  Borland also

   maintains ftp and www sites, but they don't include nearly as many files as

   the CompuServe forum.  Various other web sites have sprung up with Delphi

   files here and there; try <http://vislab-www.nps.navy.mil/~jnhodges/> or

   <http://www.cybernetics.net/users/bstowers>.


What operating systems does Delphi support?

#00000017.FAQ	From FAQ

   The only version of Delphi that has been released is for Windows 3.1. There

   is no reason why it should not run correctly under systems that provide

   Windows 3.1 emulation, like OS/2 Warp, Windows NT, etc. Borland has

   announced plans for a 32-bit version to coincide with Windows 95. It is

   rumored that this might be a free upgrade to users of Delphi 1.0, but I

   wouldn't count on it. It is also known that Delphi 1.0 does not run

   correctly on the prerelease version of Windows 95.

   Applications built in Delphi are Windows 3.1, 16-bit applications. However,

   Borland has stated that existing Delphi applications will compile

   unmodified in 32-bit Delphi.

   Francis Whiteley <whiteley@croughton.win-uk.net> points out that the

   readme.txt file for Delphi says: "Delphi has been tested under Windows 3.1,

   Windows for Workgroups 3.11, Windows NT 3.5, OS/2 Warp, and the latest pre-

   release version of Windows 95. Note that we do not recommend large-scale

   deployment of database applications running under Windows 95 until

   Microsoft certifies a release for commercial use."


What source management tools are compatible with Delphi?

#00000018.FAQ	From FAQ

   Delphi Client/Server is said to include built-in connectivity to PVCS. In

   addition, it should be possible to connect to most non-language-specific

   source control systems. However, Delphi forms are stored in non-text

   format, so a source control package must support binary data if it is to

   work with Delphi.

   If your have a source manager that simply cannot deal with binary files,

   Rick Thompson <rat@ab00.larc.nasa.gov> points out: "According to the docs

   (User Guide, pp. 94-95) you can save forms as ASCII text for editing or

   version control purposes.  ASCII forms can also be loaded and resaved in

   binary *.DFM format."

   According to Chuck Lownie <chuck@mks.com>, "MKS Source Integrity (MKS SI is

   2nd in PC/PCLAN source management market next to PVCS with over 35,000

   developers using SI) also offers integration into Delphi.  Our integration

   into Delphi is currently being shipped along with MKS Source Integrity,

   however, in a future maintenance release of Delphi, our integration will

   also be shipped in the Delphi box, similar to PVCS."


Can I use DLLs developed in C or C++ from Delphi?

#00000019.FAQ	From FAQ

   Delphi is capable of making calls to and receiving callbacks from any

   standard Windows DLL. In addition, it is said to be possible (though rather

   tricky) to get Delphi to access classes within C++ DLLs. Borland's WWW

   server has instructions on how to do this. I wasn't able to get it to work,

   but I think that's because I have weird DLLs.


Can I make calls to Delphi code from C or C++?

#00000020.FAQ	From FAQ

   Delphi can generate DLLs, which can be called from C, C++, Visual Basic,

   Powerbuilder, or anything else that understands standard Windows DLLs.

   There is an example of a database-capable DLL in the DEMOS\DB\DLL

   directory.

   As is the case in all Windows programming languages that I know of, DLLs

   are difficult to debug and will crash your system if they aren't quite

   right. Save your source code frequently.


What third-party packages are specifically known to work (or not work)

#00000021.FAQ	From FAQ

Keywords: FAQ, Third-Party, Components, Controls

   Package/Manufacturer/Tested By/Comments

   Orpheus/TurboPower Software/graham@mhn.org/Orpheus is a package of native

        VBX controls (I.E. true Delphi objects, not VBXes), including full

        source code. It's in beta test, and expected to be in full production

        by May. It has a text editor that works with up to 16Mb files, a

        virtual list box, smart data entry fields, a timer pool that allows

        multiple timers without consuming as any Windows resources, spinners,

        better tabbed notebooks, and various other things.

   Crystal Reports VBX/Crystal Services/graham@mhn.org/The version of Crystal

        Reports that is included with Visual Basic works fine. I haven't tried

        other versions. The default class name, TReport, conflicts with the

        ReportSmith class built into Delphi, so I renamed it to

        TCrystalReport.

   Spread-VBX 2.0/FarPoint Systems/graham@mhn.org/When I tried to load Spread-

        VBX, Delphi immediately crashed, and shortly thereafter my entire

        system locked up. I guess that means it isn't compatible...

   Visual Basic's Grid/Microsoft/graham@mhn.org/This loads and runs fine,

        although once again Tgrid conflicts with stuff built into Delphi, so I

        renamed it to TVBGrid. I only installed this to see if it would work;

        Delphi's built-in grids are better.

   VBTools 3D Calendar/MicroHelp/graham@mhn.org/Works fine, except that it

        isn't data-aware once you load it into Delphi.

   VBTools Card Deck/MicroHelp/graham@mhn.org/Works fine

   VBTools Dice/MicroHelp/graham@.mhn.org/Works fine

   Data Widgets/Sheridan Software/graham@mhn.org/Can be made to work, sort of;

        but no data connectivity, so what's the point?

   Hey, you! I know you've used some VBXes (or whatever) with Delphi. Please

   e-mail graham@mhn.org with your findings so that this list can become more

   complete.

   4. Database Questions.


How do I get access to a database from Delphi?

#00000022.FAQ	From FAQ

   In general, you have to go to "BDE Config" and define an alias for the

   database you want to connect to. This allows you to avoid hard-coding a

   directory path into your application; you just refer to the alias. Then,

   you create a minimum of three objects on the desktop: A Query or Table

   object that actually talks to the alias and gets some data; a Data Source

   object that links between the data and the controls, and at least one data-

   aware control.

   If you've been trying for hours to get this to work, and no matter what you

   do you just don't see anything happening, try setting the "active" property

   on the Table or Query to "True." This will open the database. I have seen

   many people get caught out by this the first time they try it.


Does Delphi support the <mumble> back-end?

#00000023.FAQ	From FAQ

   Delphi Desktop does not directly support any back-ends except for Local

   InterBase, and of course the BDE (Borland Database Engine) itself. Delphi

   Client/Server directly supports Oracle, Sybase, Informix, and InterBase. In

   both cases, you can use third-party ODBC drivers to connect to any system

   you want.


What data-aware controls come with Delphi?

#00000024.FAQ	From FAQ

   Steve Teixeira <steixeir@borland.com> says:

        Both versions contain the same data-aware components:

        TDBGrid (a data grid)

        TDBEdit (an edit control)

        TDBNavigator (a navigator with buttons to move around in a table)

        TDBLabel (a label control)

        TDBMemo (a multiline edit control useful for text blobs)

        TDBImage (a component that displays graphic fields)

        TDBRadioButton and TDBCheckBox (self-explanatory)

        TDBListBox, TDBComboBox, TDBLookupListBox, TDBLookupComboBox


Can I use the ODBC drivers that I got with <mumble>?

#00000025.FAQ	From FAQ

   Yes, generally. I have not encountered any ODBC drivers that don't work

   with Delphi, but on the other hand, I haven't tried any really exotic ones.


What about data-aware VBXes?

#00000026.FAQ	From FAQ

   Delphi only supports Level 1 VBX controls. This means that data-aware VBX

   controls *do not work* with Delphi. In general, anything that works with

   Microsoft Visual C++ should be okay in Delphi. Also, some data-aware VBX

   controls are sufficiently well-written that Delphi can make use of them and

   simply not access the data properties. See the compatibility list in

   section 3.5.


How do I write a "change password" function for a Paradox table?

#00000027.FAQ	From FAQ

   There is no way to do this within the Delphi VCL. Seems like a pretty

   serious omission to me. However, it is possible to do it by talking

   directly to the Borland Database Engine through the interface provided by

   the DBIPROCS and DBITYPES units. You call DbiDoRestructure, but set all the

   "number of" variables to zero, which makes it leave the existing values

   intact. I have code to do this, but it's a bit too long to included here.

   E-mail <graham@mhn.org> if you want it.


Why do I get errors when I call the Add method for a TFieldDefs?

#00000028.FAQ	From FAQ

   Because the documentation is wrong. There is an additional boolean flag

   that defines whether the field is required or not. The correct declaration

   for TFieldDefs.Add is as follows:

   procedure Add(const Name: string; DataType: TFieldType; Size: Word;

   Required: Boolean);


What is the procedure for connecting Delphi to an MS Access database?

#00000029.FAQ	From FAQ

   David Zaret <zaretd@il.us.swissbank.com> posted:

        Here is the step-by-step process that I took to connect my Delphi app.

        to an Access database:

          Open up the Windows Control Panel.

          Open up the ODBC "Data Sources" icon.

          ADD a new Data Source of Type ACCESS DATA.

          Provide a unique "Data Source Name" (it doesn't really matter what

          you call it - description is optional).

          Choose the Database File by clicking the "Select Database" button.

          Close the "Data Source" window.

          Open up the "Database Engine Configuration" to get to the "BDE

          Configuration Utility" screen.

          Click on the "NEW ODBC Driver" button.

          Provide a "SQL Link Driver" - once again, it doesn't really matter

          what you call it.

           Select a Default ADBC Driver of type ACCESS DATA.

           Under "Default Data Source Name" choose the name of the ADBC driver

          that you provided from the Control Panel.

           Create a new alias by clicking on the "Alis" page tab.

           Click on the "New Alias" button.

           Give the alias a name.

           Select an Alias Type of ODBC_[WHATEVER YOU CALLED IT IN STEP 11].

           Save your settings with File/Save.

           You can now close the BDE Config. Utility.

           IN YOUR PROJECT --- (I am sure that there are many ways to approach

          the next steps, but here's what I did)

             a)   Add a Tdatabase component

                  1)   Set the AliasName to the new alias that you just

                       defined.

                  2)   Provide a dummy DatabaseName.

                  3)   Set the LoginPrompt to FALSE (if you don't want

                       permission checking).

             b)   Add a TQuery component.

                  1)   Set the DatabaseName to the dummy name you provided in

                       a.2)

             c)   Add a TDataSource component.

                  1)   Set the DataSet to the name of the TQuery comp.

        And you are done!  You now have a SQL-ready, data-aware fomr that y ou

        can plop SQL into and data-aware components on to!


How can I manipulate data programmatically?

#00000030.FAQ	From FAQ

   It is sometimes desirable to write code that deals with databases but is

   not associated with any particular form or user-interface details.  To do

   this, you declare variables of type TDatabase, TTable and/or TQuery, and

   set their properties in code just as you would in the design environment.

   Make sure that you include the DB and DBTables units in your uses

   statement, or you will get "unknown identifier" errors during compilation.


What target formats can I create using Delphi?

#00000031.FAQ	From FAQ

   Delphi can create Windows 3.1 EXE files and DLL files. I am told that you

   can also create VBXes, but I have yet to figure out how you would go about

   it. Delphi does NOT create DOS EXE files.


I built a small test project. What are all these files?

#00000032.FAQ	From FAQ

   Here is a list of the file extensions created by Delphi and what they all

   mean:

   DPR - Delphi Project File. This is actually a Pascal source file; it just

        happens to be the main program for the application.

   ~DP - A backup file of the DPR file before the last save operation.

   PAS - In Delphi, PAS files are always the source code to either a unit or a

        form. The main program of an application is in the DPR file.

   ~PA - A backup of a .PAS file.

   DFM - These files are always paired with PAS files. The DFM file is the

        binary data used to set up initial data for components (IE, the

        properties you set in design mode rather than in code). You can't edit

        a DFM file with a text editor, but if you open it in Delphi, you will

        see a textual version of the contents.

   ~DF - A backup of a .DFM file.

   DCU - A compiled unit, similar in concept to an OBJ file.

   OPT - Project Options; i.e. compiler and linker settings, which form is the

        main form, what icon to use for the application, etc. Generally, the

        stuff you edit under Options/Project.

   RES - A Windows resource file; generated automatically by Delphi and

        required by the compilation process. You don't need to worry about

        this file, but don't delete it either.

   EXE - All of the above linked together into runnable format.


How can I yield the CPU to other tasks, like "DoEvents" in VB?

#00000033.FAQ	From FAQ

   The Delphi equivalent is Application.ProcessMessages. There is also an API

   function called Yield that seems to do the same thing, but it isn't safe to

   use from most Delphi applications.

   Steve Teixeira <steixeir@borland.com> explains:

        You should not use Yield() unless your application is *guaranteed* not

        to receive any messages (ie, your application contains no windows).

        Instead, the way to do this in Delphi is to call

        Application.ProcessMessages. ProcessMessage encapsulates a

        PeekMessage() loop, which is the correct "API-way" to do this.


Why do I get compile errors accessing the Sender object in events?

#00000034.FAQ	From FAQ

   If you look at the declaration, the Sender object is of type TObject, which

   is the class from which (almost) all other objects are derived. You're

   probably trying to access a property that isn't defined in TObject, like

   Text or Caption or something. For this reason, "Sender.Text" will fail, but

   if (for example) you know that the sender is of type TEdit, then you could

   use "(Sender As TEdit).Text". If you aren't certain that the Sender object

   will always be the same type, you can check it with "if (Sender is TEdit)

   then <blah>;". See section 5.14.


Are there any tools to help me migrate my applications to Delphi?

#00000035.FAQ	From FAQ

   There is an automated translator that converts Visual Basic projects to

   Delphi. I have heard from a couple people who have tried using it, and the

   results seem to be pretty mixed. It's very useful for some people, but not

   useful at all for others. It is made by:

      EarthTrek

      7 Mountain Rd.

      Burlington, MA  01803

      (617) 273-0308


What's the Delphi equivalent of Visual Basic control arrays?

#00000036.FAQ	From FAQ

   There isn't one. Delphi components do not have an Index property like VB

   controls, so you can't declare an array of them. However, there are three

   main reasons why you might want to, and each of them can be done in Delphi.

   Here's how:

   Reason 1. You want to share event handlers between different controls on a

   form.

   This is really easy. All you have to do is select the same event handler

   procedure in each of the controls' events. This is better than control

   arrays because you can even have the same event handler function across

   different kinds of control; for example, a toolbar button and a menu item

   can call the same function directly in each of their Click events.

   Reason 2. You want to be able to dynamically allocate and deallocate

   controls at run-time.

   This is also pretty easy in Delphi. Suppose you have a button on a form,

   and each time it is clicked, you want to create another, different button.

   The following sample code shows how to do this:

   procedure TForm1.Button1Click(Sender: TObject);

   var

     NewButton: TButton;

   begin

     NewButton := TButton.Create(Self);

     NewButton.Parent := Self;

   end;

   It is important to note that once this event finishes, the NewButton

   variable goes out of scope and we no longer have a pointer to the newly-

   created control. You can't deallocate a control within its own event

   handlers, so if at some point you want to remove one or more dynamically-

   created controls, you have to search for them in the Form.Controls array

   and/or maintain your own list of pointers to the controls you create.

   Assuming that there are no control event handlers running, it is safe to

   deallocate a control by just calling its Free method.

   Reason 3. You really want to access controls by number.

   I ran across this when I decided to write a board game similar to Reversi

   as a Delphi learning project. I had 100 TShape controls on a form, in a

   10x10 grid. So, I painted all the shapes in the form designer and allowed

   it to give them names like "ShapeNN", but then I also declared an array of

   pointers to controls: "Board: array[1..10, 1..10] of ^TShape;" and

   populated it in the form's Create event. This is a hundred lines of code

   that really shouldn't be necessary, but from then on I could access

   controls in a two-dimensional array, like this: "Board[3,5]^.Brush.Color :=

   clRed;" -- which is more than I could have done with VB.


How do I close a modal form? For that matter, what's the best way to

#00000037.FAQ	From FAQ

Keywords: FAQ, Close, Modal Form - Closing

   Generally speaking, you call the form's Close method. This runs the OnClose

   event, which may decide it doesn't want to close, for example if there is

   unsaved data in the form. Close doesn't free the memory associated with the

   form, unless of course you put a call to Release in the form's OnClose

   event.

   If you want to close a form without giving it a chance to argue, call the

   form's Release method. This is similar to Free, but it allows event

   handlers (e.g. OnDestroy) to finish running before the memory goes away.

   Modal forms "end their modal state" when you set the form's ModalResult

   property to anything greater than zero. If you put a button on a modal form

   and set the button's ModalResult property to some value, then when the user

   clicks on that button the form will close with the result you specified.

   You can find out what the result was by calling ShowModal as a function;

   i.e. result := Form.ShowModal.


Are there commercial applications developed in Delphi?

#00000038.FAQ	From FAQ

   Not as far as I know. Delphi hasn't been released that long--give it time.

   If you can write a commercial application in VB, then you can definitely

   write one in Delphi. Of course, Delphi itself is written in a combination

   of Delphi and assembler (or so it is said), and it's certainly a commercial

   product.

   THIS IS WRONG!

   MicroSoft Ships a Delphi App with VC++ 4.0  (They know whats best!)


Do I have to know a lot about the Windows API to use Delphi?

#00000039.FAQ	From FAQ

   There seems to be a feeling that you need to know more about Windows to use

   Delphi than you do to use Visual Basic. This isn't really true; you can get

   by in both environments with a very minimal understanding of Windows

   internals. However, in both environments, you have to know at least a

   little about the Windows API in order to really make the most of what you

   have. The difference is that Delphi gives you a lot more power to do all

   these interesting things, so you feel more limited if you don't know how.


Do I have to understand object oriented programming to use Delphi?

#00000040.FAQ	From FAQ

   Well, yes, to a point. Delphi's user interface design tools produce object-

   oriented code. However, if you're familiar with either Visual Basic or

   Powerbuilder, you probably have enough understanding of OOP to get by. You

   can do a great deal in Delphi without having to create your own objects,

   which is the point at which it becomes important to really understand

   something about them.


How does Delphi's exception handling work?

#00000041.FAQ	From FAQ

   The basic structure goes something like this:

      p := new(big_thing);

      try

        blah(p);

        foo(p);

      finally

        dispose(p);

      end;

   The first line allocates a big block of memory. Then, in the "try" block,

   we execute several statements, each of which might produce an error--or, in

   other words, "raise an event."  If an error does occur, the rest of the

   "try" block will be skipped, "finally" blocks will be executed. If there

   are no errors, then the "finally" block will be entered when the last

   statement in the "try" block completes. So, either way, the big block of

   memory gets freed. These "try/finally" blocks will trap anything up to and

   including a Windows GPF.

   In addition, you can construct "except" blocks which can provide local

   error handling either for all errors or for particular types of error; and

   you can also create your own global error handler to trap exceptions that

   aren't otherwise handled by try blocks. See Chapter 7 in the Delphi User's

   Guide for more details.


Does Delphi use Pascal or C style strings?

#00000042.FAQ	From FAQ

   Both. Delphi has two different sets of string manipulation functions, one

   for null-terminated strings, and one for Pascal-type (I.E. length byte)

   strings. You will find yourself stumbling across this distinction from time

   to time. Mostly, there are Delphi functions that wrap around the most

   common Windows API functions; for example, MessageBox, which is a Windows

   API call, requires a PChar; but Delphi also has MessageDlg, which accepts

   Pascal-type strings.

   If you have text in a Pascal string and you want to pass it to a function

   that expects a PChar, the following code is a "quick and dirty" way of

   doing it, assuming that s is of type string and that the string has room

   for one more character:

        s[length(s)+1] := #0;     { Appends a null to the end of the string }

        C_Style_Function(@s[1]);  { @s[1] is a PChar to the beginning of s }


How does Delphi handle Windows callbacks?

#00000043.FAQ	From FAQ

   Just like C: You can get a far pointer to your callback procedure (you have

   to remember to declare it with the "far" qualifier, unless you have {F$+}

   in effect to force all calls to be far), pass the pointer to the Windows

   callback function, and there it is.


How does Run-Time Type Information (RTTI) work?

#00000044.FAQ	From FAQ

   There are two new operators: "as" and "is."  The "as" operator is a

   protected typecast. You can use it to force the compiler to treat an object

   of one type as another type, but if at run-time the typecast is not

   properly compatible, then you will get an error. For example, if you have a

   class called TSport, with descendants TBasketball and TFootball, you might

   want a variable of type TSport--but you might also happen to know at a

   certain point in the program that this variable actually contains an

   instance of a TFootball. So, you can refer to it as (MySport as TFootball)

   in order to get access to its football-specific properties. However, if you

   are wrong and somehow a TBasketball gets passed in, instead of just looking

   at the data in some oddball way like a regular typecast, this will generate

   an error.

   The "is" operator is used to compare an instance of an object to a class of

   objects, to see if a typecast using "as" will work. If you have a variable

   MySport of type TSport, and it currently contains an instance of a

   TBasketball, then the following statements are true:

      (MySport is TSport)

      (MySport is TBasketball)

      not (MySport is TFootball)

   The combination of these two operators might lead to code such as the

   following:

      function player_goodness(var MySport: TSport): integer;

      begin

        if (MySport is TBasketball) then

          player_goodness := (MySport as TBasketball).rebound_shots

        else if (MySport is TFootball) then

          player_goodness := (MySport as TFootball).total_yardage;

      end;

   It has been pointed out that this would be better implemented as a method

   which TSport defines and TBasketball and TFootball override, but then it

   wouldn't illustrate how RTTI works, would it? :-)


I'm creating a toolbar, but I have icons, not bitmaps. Help!

#00000045.FAQ	From FAQ

   Your best bet is to own something like HiJaak which can do the conversion

   directly. However, assuming that you have nothing but Windows and Delphi,

   the following procedure can be used to convert an icon to a bitmap:

     Display the icon somehow. Doesn't matter how you do it.

     Press Alt-PrintScreen to copy the current window to the clipboard.

     Load Paintbrush and do an Edit/Paste.

     Highlight the icon using the square selection tool and do an Edit/Copy.

     Go to Options/Image Attributes and set the working area to 32x32 pixels.

     Do an Edit/Paste again.

     Save the result as a BMP file.


When I use the Glyph property, how do I know which color is transparent?

#00000046.FAQ	From FAQ

   Delphi always assumes that the color of the bottom left-hand corner pixel

   is the background color and should be displayed as transparent. Yes, it

   took me a while to figure this out. It's not documented anywhere, but if

   you have the VCL source, you can look at the code in BUTTONS.PAS.


How can I make my Delphi application respond to Windows messages?

#00000047.FAQ	From FAQ

   Using WM_WININICHANGED as an example, Chuck Jazdzewski

<cjaz@borland.com>

   says:

        Declaring a method in a TForm will allow you to handle

        WM_WININICHANGED messages:

            procedure WMWinIniChange(var Message: TMessage);

              message WM_WININICHANGE;

        The body of the implementation could look like:

        procedure TForm1.WMWinIniChange(var Message: TMessage);

        begin

          inherited;

          {.. react to someone mucking with control panel ..}

        end;

        The call to "inherited" is important.  Note also that message

        handlers are special when calling their inherited since you

        don't refer to the name of the inherited.  This is because

        the inherited is referring to the inherited message handler for

        this message number, which might not have a visible name or

        or even the same name as you have given it, or in some cases,

        might not even exist (in which case you are really calling

        DefaultHandler).


How can I allocate blocks of memory larger than 64k?

#00000048.FAQ	From FAQ

   Reinier Sterkenburg <sterkenb@pml.tno.nl> says:

        The answer is: use GlobalAlloc and GlobalLock from the WinProcs unit.

        New question is then: why can't we use GlobalAllocPtr anymore?

        Answer: I don't know.


Is it possible to write a Windows screen saver in Delphi?

#00000049.FAQ	From FAQ

   Thomas W Wolf <twwolf@cacd.rockwell.com> says:

        Someone posted a message requesting information on how to use Delphi

        for a screen saver.

        a) In the project file (*.dpr) add '{$D SCRNSAVE <saver name>} after

        the uses clause.

        b) On the main form, turn off the border and icon controls. In the

        activate method set the form left and top to 0, and set the

        Windowstate to wsMaximize.

        c) In the form create method, set the application.OnMessage to a

        method that controls the deactivation of the screen saver. Set the

        application.OnIdle method to whatever display method for the saver.

        d) In the form create method the command line should be tested for /c

        and /s. These are the command line parameters windows uses to define

        whether the screensaver should run or configure. (/c is for

        configuration)

        e) Compile the program, and rename the .exe to .scr. Move it to the

        windows directory, and it should show up in the control panel.


I'm trying to call <mumble> from Delphi and it GPFs.  What's up?

#00000050.FAQ	From FAQ

   Based on the number of postings to comp.lang.pascal, it would seem that by

   far the largest number of problems calling Windows API functions or non-

   Delphi DLLs are caused by passing Pascal-style strings to functions that

   expect null-terminated (PChar) strings.  This is the first thing you should

   check if you get a GPF or other strange results when calling an external

   function.  See section 5.12 for more information on which type of strings

   go where.


How can I add pages to a TTabbedNotebook at run-time?

#00000051.FAQ	From FAQ

   The following source code, which assumes that you have a tabbed notebook

   called TabbedNotebook1, will add a new page that contains an "OK" button:

   procedure whatever_whenever;

   var

        NewPage: TTabPage;

        NewPageNumber: word;

        NewButton: TButton;

   begin

        {Create the new TTabPage object}

        NewPage := TTabPage.Create(Application);

        {The page must be a child of the notebook}

        TabbedNotebook1.InsertControl(NewPage);

        {Add text to the notebook's Pages property; this will cause the new

        page to be added as the last tab on the notebook}

        NewPageNumber := TabbedNotebook1.Pages.Add(`New Page');

        TabbedNotebook1.PagesObjects[NewPageNumber] := NewPage;

        {The page needs controls on it; here's how to add one}

        NewButton := TButton.Create(Self);

        (TabbedNotebook1.Pages.Objects[NewPageNumber] as TWinControl)

           .InsertControl(NewButton);

        NewButton.Top := 10;

        NewButton.Height := 30;

        NewButton.Width := 100;

        NewButton.Caption := `OK';

   end;


I'm painting complex graphics.  How can I speed up redrawing?

#00000052.FAQ	From FAQ

   Steve Teixeira <steixeir@borland.com> says:

        Use a TBitmap component as a memory DC.  You can then copy from

        Bitmap.Canvas to your form's Canvas.


How can I have MDI child windows?

#00000053.FAQ	From FAQ

   Steve Teixeira <steixeir@borland.com> says:

        You can't hide MDI children.  Windows does weird things when you try

        to hide MDI children, so VCL doesn't permit it.


How do I write a global error handler?

#00000054.FAQ	From FAQ

   Use the Application.OnException event.  Look in the help under "application

   events" for details of how to create and attach an event handler to the

   application variable.


Why do I get exception messages even though I'm in protected code?

#00000055.FAQ	From FAQ

   By default, the internal debugger will halt any time there is an exception,

   even if the exception is trapped by code.  This can often be useful for

   debugging purposes.  If it offends you, turn it off.  You control it from

   the Options/Environment menu.


I've added code to my OnKeyPress event that traps Enter keys, but ...

#00000056.FAQ	From FAQ

   I've added code to my OnKeyPress event that traps Enter keys, but it

   keeps beeping at me and/or activating the default button. How do I make it

   stop?

   The problem is that even though you're running your own handler code, you

   are also allowing the Enter key to pass through and activate the default

   behavior for an Enter key. In order to prevent this, set key := 0, which

   will send a null keystroke through to the default handler.


I want to modify a component's properties at run-time, but ...

#00000057.FAQ	From FAQ

   I want to modify a component's properties at run-time, but it isn't

   convenient to store a pointer to the component. Is there an easy way to get

   access to it?

   Use the library function FindComponent to search by name. If you need to

   search by properties other than name, iterate through the form's Components

   array.


Is there anything in Delphi similar to the VB "setup wizard?"

#00000058.FAQ	From FAQ

   No. There are some third-party tools available, but out of the box Delphi

   does not have anything to automate the creation of setup disks. You can of

   course write your setup program in Delphi, but you have to write it

   yourself. If you do decide to use a third-party installation tool, check

   out Chief's Installer Pro. You can get it via anonymous ftp to

   ftp.demon.co.uk as /pub/ibmpc/windows/chief/pro/cinstp17.zip.


What files am I allowed to redistribute with my applications?

#00000059.FAQ	From FAQ

   If you have Delphi Desktop, you are allowed to redistribute run-time

   versions of the Borland Database Engine and of ReportSmith. Of course, you

   can also distribute the EXE or DLL files you create yourself. Borland has

   some rather odd and overly restrictive licensing terms; for example, your

   programs are required to bear a valid copyright notice (if not yours, then

   Borland's)--which seems to mean that you can't create public domain

   applications using Delphi. Also, if you distribute the Borland Database

   Engine, you are required to send out the whole thing with all relevant

   drivers. This is because other, previously-installed applications may also

   use BDE functions, and if you take away their drivers, well, that's a bad

   thing.


What other files do I need to send with a Delphi EXE

#00000060.FAQ	From FAQ

   If I want to send out a Delphi-compiled EXE file, what other files do I

   need to send with it?

   None. Everything is compiled into the .EXE file. Of course, if you've

   developed other files (like a HLP file, data files, etc.), or if you're

   using VBX files, then you have to send them as well. If you use VBX files,

   you must also include BIVBX11.DLL.

   If the application uses database functions, you also have to include the

   Borland Database Engine. You can just distribute the two pre-packaged disks

   on the Delphi CD (they don't get installed to your hard drive). And if the

   application uses ReportSmith, you have to distribute the ReportSmith run-

   time. These are big; the BDE is two disks and ReportSmith is five.


I want to distribute a database application, but I don't want to ...

#00000061.FAQ	From FAQ

   I want to distribute a database application, but I don't want to force

   all my users to create BDE aliases. What do I do?

   The simplest answer is to avoid using aliases in your application.

   Everyting you can set in an alias, you can also set as properties or in the

   Params section of a TDatabase object. For example, if you are accessing

   Paradox files, you can add a "PATH=d:\dir\path" line to the Params

   collection, avoiding the need to use a BDE alias to specify the directory

   where the files reside.


Several general questions

#1000.FAQ	From: jeroenp@dragons.nest.nl (Jeroen Pluimers)

Saturday March 04 1995 23:21, Marc@landscap.demon.co.uk wrote:

 > 1) Can Delphi (NOT Delphi Client/Server) handle multi-user database

 > tables?

Yes. Both dBase and Paradox tables can be stored remotely so multiple users

can

access them. Of course, this is as safe as using Paradox, dBase, Clipper, etc

in a networked environment: every user can screw up the database (especially

the indexes are vulnerable) so making regular back-ups is essential.

 > 2) does it have a hierarchical list control (like file manager)

Yes.

 > 3) Can it link dynamically to it's run time libraries if you really

 > want it to (I might want to have many Delphi Apps without code

 > duplication)?

You could write something like this on your own. It is not recommended though,

because of DLL versioning problems.

 > 4) Can you link in (via DLL) C++ classes and use them as if they were

 > Delphi classes, or can DLL imports only be functions?

This should be possible. I'm planning on writing an example on this in April.

 > 5) Does it have multiple inheritance? (I think not)

I'm glad it doesn't. BTW: Lot's of C++ gurus are glad for this too.

 > 6) Will there be un upgrade price from Delphi desktop to Client/Server

Yes, the upgrade between Delphi and Delphi Client/Server is the difference in

price. Of course this excludes shipping and handling.

 > 7) How much will the 32-bit upgrade cost?

Pricing of new products is determined only a few weeks in advance. So nobody

knows anything about this.

 > 8) Can you intercept the Database Control methods, so that instead of

 > using InterBase/ODBC I can call an external DLL to get data?

This will be really hard. Of course it is possible, but it will cost a lot of

trouble as you have to rework parts of the interface to BDE (Borland Database

Engine).

Jeroen

From: Steve Macdonald <macdons@io.org>

Marc@landscap.demon.co.uk (Marc Palmer) wrote:

>

>

> I have some questions for those 'in the know' :

>

> 1) Can Delphi (NOT Delphi Client/Server) handle multi-user database

> tables? Does it come with any database drivers that could be used to

> provide multi-user access to tables in a LAN (i.e. WinWorkgroups 3.11

> or Novell) ?

The "cheap" Delphi has native support for dBase and Paradox tables

and can be used to build multi-user apps using those data

storage formats. It will also work with ODBC drivers which

allow you to connect to virtually anything. For serious

client/server apps though the "expensive" Delphi is well

worth its hefty price since it comes with native mode drivers

for Oracle, SQL Server, etc. If you only plan to do small

LAN-based apps (up to about 25 users) then the regular version

should suffice.

> 2) does it have a hierarchical list control (like file manager)

Yes. At least in the beta copy which I have. The tree control

is pretty decent but not as high powered as some which are

available as VBX's.

> 3) Can it link dynamically to it's run time libraries if you really

> want it to (I might want to have many Delphi Apps without code

> duplication)?

Delphi provides excellent mechanisms for sharing forms and other

objects between projects. You can define as basic form (say

a database login form), compile it to a Delphi "component" and

then re-use it any time by simply selecting it from the "gallery".

> 4) Can you link in (via DLL) C++ classes and use them as if they were

> Delphi classes, or can DLL imports only be functions?

Haven't tried this but I don't know of any technical reason why

you could not do this. Anyone else?

> 5) Does it have multiple inheritance? (I think not)

No.

> 6) Will there be un upgrade price from Delphi desktop to Client/Server

Don't know.

> 7) How much will the 32-bit upgrade cost?

Ditto.

> 8) Can you intercept the Database Control methods, so that instead of

> using InterBase/ODBC I can call an external DLL to get data?

It would probably be simpler to deal directly with the DLL although

I would do this only as a last resort.

Regards, Steve.

From: christmn@cyberport.net (Richard)

In article <3jbn46$fqs@ionews.io.org> Steve Macdonald <macdons@io.org> writes:

>From: Steve Macdonald <macdons@io.org>

>Subject: Re: Yet more Delphi questions

>Date: 5 Mar 1995 06:52:54 GMT

>Marc@landscap.demon.co.uk (Marc Palmer) wrote:

>>

>>

>> I have some questions for those 'in the know' :

[ snip...]

>> 3) Can it link dynamically to it's run time libraries if you really

>> want it to (I might want to have many Delphi Apps without code

>> duplication)?

>Delphi provides excellent mechanisms for sharing forms and other

>objects between projects. You can define as basic form (say

>a database login form), compile it to a Delphi "component" and

>then re-use it any time by simply selecting it from the "gallery".

[snip...]

Steve,

I wonder if you missed the point here. Let me ask this question again.

Can Delphi's VCL be compiled into a DLL as OWL can be. How about the runtime

library? If one is to put several Delphi programs on the same system, it would

be an advantage to use the VCL and runtime in DLL form like in BCW. Though

this seems to fly in the face of the "No DLL's required with Delphi" sales

pitch, it is entirely different concept than VB's DLL based interpreter.

Also, I speak here of the "option" of dynamic linking. Do you know if Delphi

can link dynamically as I've suggested?

Richard

From: Steve Teixeira <steixeir@borland.com>

christmn@cyberport.net (Richard) wrote:

>

> In article <3jbn46$fqs@ionews.io.org> Steve Macdonald <macdons@io.org>

writes:

> >From: Steve Macdonald <macdons@io.org>

> >Subject: Re: Yet more Delphi questions

> >Date: 5 Mar 1995 06:52:54 GMT

>

> >Marc@landscap.demon.co.uk (Marc Palmer) wrote:

> >>

> >>

>

> >> I have some questions for those 'in the know' :

>

> [ snip...]

>

> >> 3) Can it link dynamically to it's run time libraries if you really

> >> want it to (I might want to have many Delphi Apps without code

> >> duplication)?

>

> >Delphi provides excellent mechanisms for sharing forms and other

> >objects between projects. You can define as basic form (say

> >a database login form), compile it to a Delphi "component" and

> >then re-use it any time by simply selecting it from the "gallery".

>

> [snip...]

>

> Steve,

>

> I wonder if you missed the point here. Let me ask this question again.

>

> Can Delphi's VCL be compiled into a DLL as OWL can be. How about the runtime

> library? If one is to put several Delphi programs on the same system, it

would

> be an advantage to use the VCL and runtime in DLL form like in BCW. Though

> this seems to fly in the face of the "No DLL's required with Delphi" sales

> pitch, it is entirely different concept than VB's DLL based interpreter.

> Also, I speak here of the "option" of dynamic linking. Do you know if Delphi

> can link dynamically as I've suggested?

>

> Richard

No, you cannot dynamically link VCL into your Delphi apps.  However, Delphi's

compiler takes advantage of "smart linking" to throw most unused code and

data out of the .EXE.

        -Steve Teixeira

         steixeir@borland.com

From: pacsoft@netcom.com (Wilhelm Sarasalo)

Subject: Re: Yet more Delphi questions

Date: Thu, 9 Mar 1995 21:30:43 GMT

Marc Palmer (Marc@landscap.demon.co.uk) wrote:

---- deletia ----

: Yes that's what *I* meant when I asked the question. Here's an example

: of how my app may be structure (sizes are estimates - I don't have delphi

yet):

: DATABASE.EXE  700K

: REPORTS.EXE     800K

: TOOLS.EXE       900K

:            ---------

:                2400K

My experience with actual Delphi sizes (off my head, I am not at my office):

EXE's:

Smallest possible application,

No forms, nothing, makes the

the windows bell sound, no icon:     2.4K and up

DOS app in a Window                   24K and up

A Form (Hello World [O.K])           160K and up

Database access (may use DLL's,

I haven't checked)                   450K and up

: Now, if there is a common runtime overhead of say 200K (I think that's

conservative)

: then there is 400K of my customers hard disk *AND* memory being wasted.

: If all three apps are loaded at once, then there is 600K of RAM being used

for runtime

: code, where 200K would have worked if it was in a DLL.

Very excellent point. I don't know yet, but since things can be organized

into libraries that get compiled into DLL's and since one can freely edit

the source code once Delphi has generated it, I don't see why one couldn't

try to put every last byte of commonly shared code into DLL's. I don't

think Delphi comes with anything to help you here, at least not Delphi 1.0,

but it looks doable. (how you organize your code into DLL's is of course

an art of compromize)

: I think the Static linking of Delphi should be optional. I suspect they made

it

: mandatory to remove the need to distribute DLLs (depending on which ones you

use).

: I understand this thinking, because the VBRUN DLL is pretty big. But that

argument

: falls down if you are providing more than one app. Now if Delphi let you

choose a

: Dynamic Link option, it could automatically tell you which DLLs are used,

hence

: making the task of distributing your software much easier than with C/C++.

Keep us posted if you find good ways of doing this. Or if you find that it

can't be done.

I hope this gave you some ideas.        finger pacsoft@netcom.com|more

Have Fun!                                                      Wilhelm

From: Raymond@mcgltd.demon.co.uk (Raymond Wilson)

In article <558110028wnr@landscap.demon.co.uk>

           Marc@landscap.demon.co.uk "Marc Palmer" writes:

> In article: <3jle2l$op4@druid.borland.com>  Steve Teixeira

>  <steixeir@borland.com> writes:

> > No, you cannot dynamically link VCL into your Delphi apps.  However,

Delphi's

> > compiler takes advantage of "smart linking" to throw most unused code and

> > data out of the .EXE.

>

> But surely that's not too hot! If I give my customers ten EXEs, they'll have

> ten duplicates of core code. What's the minimum overhead of a Delphi app?

> 100K ? That's still 10*100K instead of 1*100K.

You are right, including 10 copies of core code is a waste of space so it

would be nice to have this in a DLL. However, taking a pragmatic approach,

disk is so cheap now (way under the $1/Meg mark), that a 100 or even 200K

overhead is not enough to worry about. In fact, here in the UK we can get

540Mb disks for 130 pounds (about 200 US dollars). Its almost cheap enough

to install your software on 500 Mb disk and give that to the user when they

buy the software!!! (In fact, it is already cheap enough and I expect to

see this practice start happening soon).

Raymond.

--

Raymond Wilson,      Software Engineer.      Morgan Collis Group Ltd,

                                             The Mill, Millbrook Close,

Yes, they ARE fond of mills here!            St. James Mill Rd,

Ph: +44 604 580-980  Fax: +44 604 589-208    Northampton NN5 5JF, Britain.

From: slp@uno.edu

In article <mac.104.2F605440@zeus.hsrc.ac.za>, mac@zeus.hsrc.ac.za (Malcolm

Coulter) writes:

>In article <558110028wnr@landscap.demon.co.uk> Marc@landscap.demon.co.uk

(Marc Palmer) writes:

[Deletia]

>>But surely that's not too hot! If I give my customers ten EXEs, they'll have

>>ten duplicates of core code. What's the minimum overhead of a Delphi app?

>>100K ? That's still 10*100K instead of 1*100K.

>-----------------------------------------------------------------------------

-

>I'm with you here Marc. The Object Pascal compiler may do a good job of

>eliminating duplicate or unused code WITHIN a program, but does nothing about

>the DUPLICATION of code BETWEEN programs.

>

>One of the great values of DLLs (there are many) is there ability to allow

one

>to cut down on inter-program duplication.

This is a great goal, but until all the big guys get together on this

it's going to remain a problem.  I shudder to think how many times the

code needed to interpret (for instance) a .PCX file is duplicated on my

disk because each and every application that needs to do that "reinvents

the wheel" (off the top of my head: PaintBrush, Microsoft Word,

PagePlus, Hijaak, PhotoStyler, PaintShop Pro; that's 6x redundancy at

least).   Or how about applications that use their own file open/save

dialog code rather than using CommDlg (of which Borland itself is quite

guilty)?  How much difference is your "paltry" 100k going to make

against all this redundancy?

>You can of course have DLLs with components, but the components are no longer

>objects to the program using the DLL.

>

>One of the great problems still to be tackled by the main stream (which may

>not always mean best) languages is the "objectization' of DLLs and other

>executables.

>

>If a language developer could find a practical efficient way of doing this

>they would have a huge commercial advantage until the imitations started

>rolling out.

>

>But first they need to become a bit less hierarchy-first-encapsulation-second

>in their orientation to objects.

>

>There are no theoretical problems- we only need someone of creative

brilliance

>to see the road to implementation.

Well, I think true OBJECT ORIENTATION in this context would be files

(documents might be a better term) that know how to load, display, edit,

and save themselves; then an application that needed to access such a

file would just ask it do whatever was needed.

best,

-* Stephen *-

Stephen Posey

SLP@uno.edu

University of New Orleans


Delphi's Directories

#1001.FAQ	From: james.obrien@yale.edu (James A. O'Brien)

>Anyway, I need read a list of files in a directory.

>Under Unix I would call the standard libc functions opendir(),

>readdir(), closedir(), etc...  How do I do this in Delphi?

>I spent about an hour trying to find anything like this in the

Don't have Delphi in front of me right now, but I'd do something like using a

TDirectoryListBox (make it hidden, or off to the left of the form!) and pull

the names out of there.  It's a different way of looking at the universe, but

it works!

Jim.

From: ediss@teleport.com

Andrew Scherpbier (turtle@sciences.sdsu.edu) wrote:

: (I should probably mention that I am a Unix C++ programmer and

: that my knowledge of DOS and MS-Windows is minimal.)

: Anyway, I need read a list of files in a directory.

: Under Unix I would call the standard libc functions opendir(),

Search help and/or documentation for info on "common dialogs"

--

ediss@teleport.com

From: The Green Meddler <kilgalen@tde.com>

turtle@sciences.sdsu.edu (Andrew Scherpbier) wrote:

>

> Greetings--

>

> I just got Delphi Yesterday and have already started writing

> an application.  Today I got stuck, however.

> (I should probably mention that I am a Unix C++ programmer and

> that my knowledge of DOS and MS-Windows is minimal.)

> Anyway, I need read a list of files in a directory.

> Under Unix I would call the standard libc functions opendir(),

> readdir(), closedir(), etc...  How do I do this in Delphi?

Delphi's file management routines are found in the help system

under "File management routines" (duhh); directory management routines

are found by the function name; start at DirectoryExists and work

around.  not the best way to document this stuff..

> I spent about an hour trying to find anything like this in the

> online manuals (both the help and acrobat stuff) but have come

> up with a complete blank.

> I know it can be done since all the builtin OpenDiaglog thingies

> seem to do it just fine!  (I heard the Delphi was written in

> Delphi, so I KNOW it has to be possible!!!)

>

> Can a kind soul please let me in on this secret?  (Example code

> would be the best!)

>

> Thanks in advance!

>

> --Andrew

> _____________________________________________________________________

> Andrew Scherpbier, System Analyst  Email: Andrew@sdsu.edu

> College of Sciences                Voice: (619) 594-5026

> San Diego State University         Fax:   (619) 594-6381

> San Diego, California 92182-4637   WWW:   http://www.sdsu.edu/~turtle

GM


Frequently Asked Questions - What is Delphi?
What is Delphi?

#1002.FAQ	From: gwitty@sccsi.com (Gary Witty)

In article <3jbm0v$ge1@tdelx01.tde.com>,

   The Green Meddler <kilgalen@tde.com> wrote:

>Tom Cabanski <sig@teleport.com> wrote:

>>

>> steinway@eden.rutgers.edu (John Lanzetta) wrote:

>> >

>> > I think I missed the boat!  Just exactly what is DELPHI?  Is it a

>> > language or a programming environment?  What are its pros and cons?  I

>> > try to keep up with developments in the Turbo/Borland pascal world, so

>> > how come the so-called "main stream computer media" never picked up on

>> > this?

[snip]

>so? eventually windows will run on anything...

[Philosophising mode on]

Back when IBM and MS were co-developing OS/2, both parties were saying "wave

of the future" about OS/2, and that Windows would be the environment for

everyone with shit for brains. That last part was heavy on paraphrase, but the

irony is so thick you can swim in it.

Microsoft bought its way to where it is.

>> Lacks multiple inheritance

>

>compiler-supported MI. you can still do the same with

>some code merging. and considering the problems with

>slicing in C++, i don't see this as a con...

Having been working with C++ since the AT&T pre-compiler days on Unix, I have

to say that is really a matter of opinion; mine being that MI can solve a

number of OOD problems in a hurry.

>> Sold by a company that may be in trouble

>

>Borland made a mistake buying DBase and not giving up on it

>sooner. but their core business is strong, and i for one

>think delphi will keep them afloat for a number of years..

>

>> Not C (I disagree with these two but some people...)

>> Not Microsoft

>>

>these last two are PROS, not cons! (G)

The two digressions really need to be grouped together for real comment, but

for what it's worth...

I've taught Pascal for years. My first presonal Pascal compiler was Turbo

Pascal 2.0, back in 1987. I loved it.

Likewise, my first C compiler was Turbo C 1.0 ($64.00) and I've kept it

current ever since.

But that was back in the "good ol' days" when Borland was looking like _the_

computer language company. I even remember Phillipe Kahn talking about "Turbo

Ada" to compliment its already extensive line-up of languages (Turbo Pascal,

Turbo C, Turbo Basic, Turbo Prolog)...

Yes, Borland paid way too much money for dBase. And they didn't even really

buy dBase, they bought a damned expensive mailing list. Ashton-Tate didn't

help when it knew that the dbase language was developed at a university (and

thus PD). I think Borland wanted to shift from development to end-user

horizontal products (where the real money is). It laready had Interbase and

Paradox, dBase was to be the center jewel in the crown. Guess it didn't work

out that way.

Borland's biggest problem is the fact that they haven't ever really developed

a good idea in-house, they've bought it from someone else. And any programmer

knows that it it is at least as difficult in maintaining someone else's code

than developing your own; and most of the time it's much more difficult.

But yet, there are two real unique opportunities for Borland to exploit if

they can spare the advertising dollars:

1) Borland is still the leader in database technology. A couple of years ago,

they had an opportunity like no other to acquire the ailing Oracle

corporation. Personally, I think non-PC computer systems frighten Borland, and

if so, kiss 'em bye-bye. But even with that, if Borland can spare the

advertising dollars and developers, their database market can really take off

if they punp enough money into making people believe their products are the

best (even if they're not). Just look at Microsoft; they pumped an

astronomical amount of money into hyping windows as the OS of the future.

It's not. It was, is, and always will be an inferior OS. But here we are with

Windows. Think about it.

2) Borland made a good thing with Delphi, but shouldn't stop there. What is

Delphi? It's a Pascal compiler with a fancy code-generator that makes use of

Object-Pascal and OO concepts. Now, Phillipe Kahn is betting the farm on the

success of this one product. Bad move. What they should do is put the same

wrapper on their C++ compiler and the same on an Ada compiler they should

develop, and put these products on every platform that will support it;

including OS/2, Motif/X-Windows, NextStep, AIX, and few others I can't think

of right now. If you'll look at the growing trends in development,

cross-platform and client-server is in, and will be for years to come. Object

Pascal is not implemented on as many platforms as C++, and I mentioned Ada

because the US Government is still the biggest customer for software in the

world, (and always will be) and they really like Ada.

IBM has a superior OS in Warp. They have the funds to out-spend MS on hype,

and if they do, there might be a major shift in the OS market. The big

question is will they. If so, and Borland has no plans on implementing a

native OS/2 version of their product...

My opinions, for what they're worth...

     (o) (o)         Gary Witty            Black Gold BBS

--oOO--(_)--OOo--------------------------------------------------------

           INTERNET: gary.witty@bgbbs.com  Oklahoma's Biggest and Best!

               FIDO: 1:170/309             (918) 272-7779

                            It's sad to live in a society where an entire

                          family can be torn apart by something as simple

                          as a pack of wild dogs...


Can Delphi create VCL's for itself?

#1003.FAQ	From: Steve Teixeira <steixeir@borland.com>

jgilbert@nyx10.cs.du.edu (Jeremiah Gilbert) wrote:

>

> Can Delphi create VCL's for itself?  If so, how?

>

> Thanks!

>

VCL is a class framework, like OWL or MFC.  I think you mean, "can you create

Delphi components in Delphi?"

The answer is yes.  You can learn how from the Component Writer's Guide,

which ships with Delphi. We also ship the source code to all of the

components found on the "Samples" page.

        -Steve Teixeira

         steixeir@borland.com

From: clb@prism.mindware.brisnet.org.au (Chris Burke)

Jeremiah Gilbert (jgilbert@nyx10.cs.du.edu) wrote:

: Can Delphi create VCL's for itself?  If so, how?

: Thanks!

There is an example of a simple visual control called Gradient.pas on

the Borland AUstralia BBS in the Delphi area ph +61 2 9111024.

It will give you a simple example of default and user defined behaviour

as well as properties.

--

 Christopher Burke           \ "Be positive,     \             CUSTOM COMPUTER

 MindWare, PO Box 1247         \    become         \     SOFTWARE(Dos+Windows)

 Carindale Q. 4152 AUSTRALIA     \    a proton"      \    and SYSTEMS ANALYSIS

 clb@prism.mindware.brisnet.org.au \ Eric Lectron('88) \ Phone:+61-(7)-3984000

Subject: Re: Can Delphi create VCL's for itself?

mark@myatt.demon.co.uk (Mark Myatt) wrote:

>

> In article <3jkbgb$mlr@nyx10.cs.du.edu>

>            jgilbert@nyx10.cs.du.edu "Jeremiah Gilbert" writes:

>

> -> Can Delphi create VCL's for itself?  If so, how?

>

> It's in the manual!

more specifically, check the component writer's guide. it gives

complete instructions.

it also contains a false statement:

when you are putting the name of a bitmap for the component

palette into the image editor's DCR file, it says in the guide

that the name isn't case sensitive. WRONGO, JACK! i fought for

a day before finally realizing that all the component names in

delphi's own DCR files are all uppercase. switched mine to uppercase

and bingo, there it was.

documentation bug numero uno?

GM

From: slp@uno.edu

In article <3jpvqc$i9@tdelx01.tde.com>, The Green Meddler <kilgalen@tde.com>

writes:

>mark@myatt.demon.co.uk (Mark Myatt) wrote:

>>

>> In article <3jkbgb$mlr@nyx10.cs.du.edu>

>>            jgilbert@nyx10.cs.du.edu "Jeremiah Gilbert" writes:

>>

>> -> Can Delphi create VCL's for itself?  If so, how?

>>

>> It's in the manual!

>more specifically, check the component writer's guide. it gives

>complete instructions.

>

>it also contains a false statement:

>

>when you are putting the name of a bitmap for the component

>palette into the image editor's DCR file, it says in the guide

>that the name isn't case sensitive. WRONGO, JACK! i fought for

>a day before finally realizing that all the component names in

>delphi's own DCR files are all uppercase. switched mine to uppercase

>and bingo, there it was.

>

>documentation bug numero uno?

Sadly, no, the example code on page 97, chapter 3 for creating

an MDI child window doesn't work.  The OnClick message handler should

look more like:

procedure TForm1.SpeedButton1Click( Sender : TObject ) ;

var

  MyForm : TForm2 ;    (* instance of the Child Window type *)

begin

  MyForm := TForm2.Create( Self ) ;

end ;

Rather than calling TForm2.Show; or, at least, that's what I gleaned

from working with the sample MDI application in chapter 10.

Also, step 3 reads:

"Add a Panel component to /Form1/, and change its /Alignment/ property

to /AlTop/."  There is no property named "Alignment", there's one named

"Align" which seems to fill the bill.

>

>GM

>

HTH

-* Stephen *-

Stephen Posey

SLP@uno.edu

University of New Orleans

From: tax@clark.net (Tax Analysts)

slp@uno.edu wrote:

: >documentation bug numero uno?

: Sadly, no, the example code on page 97, chapter 3 for creating

: an MDI child window doesn't work.  The OnClick message handler should

: look more like:

I found that one (and wasn't sure how to make it work right; you've

given me a clue), and one or two others.  For the most part, so far,

the examples seem to be good and do show you how to do things in

Delphi.  Windows/OOP/GUI intimidated me before this.  I just wish that

someone had actually *tried* the examples before letting them go to

press.  As a programmer and former copyeditor, it seems like a

no-brainer that this should've been done. . . .

That said, I'm very impressed with Delphi, so far!  :)

Kendall

From: The Green Meddler <kilgalen@tde.com>

slp@uno.edu wrote:

>

> In article <3jpvqc$i9@tdelx01.tde.com>, The Green Meddler <kilgalen@tde.com>

writes:

> >mark@myatt.demon.co.uk (Mark Myatt) wrote:

> >>

> >> In article <3jkbgb$mlr@nyx10.cs.du.edu>

> >>            jgilbert@nyx10.cs.du.edu "Jeremiah Gilbert" writes:

> >>

> >> -> Can Delphi create VCL's for itself?  If so, how?

> >>

> >> It's in the manual!

> >more specifically, check the component writer's guide. it gives

> >complete instructions.

> >

> >it also contains a false statement:

> >

> >when you are putting the name of a bitmap for the component

> >palette into the image editor's DCR file, it says in the guide

> >that the name isn't case sensitive. WRONGO, JACK! i fought for

> >a day before finally realizing that all the component names in

> >delphi's own DCR files are all uppercase. switched mine to uppercase

> >and bingo, there it was.

> >

> >documentation bug numero uno?

>

> Sadly, no, the example code on page 97, chapter 3 for creating

> an MDI child window doesn't work.  The OnClick message handler should

> look more like:

>

> procedure TForm1.SpeedButton1Click( Sender : TObject ) ;

> var

>   MyForm : TForm2 ;    (* instance of the Child Window type *)

> begin

>   MyForm := TForm2.Create( Self ) ;

> end ;

>

> Rather than calling TForm2.Show; or, at least, that's what I gleaned

> from working with the sample MDI application in chapter 10.

>

> Also, step 3 reads:

> "Add a Panel component to /Form1/, and change its /Alignment/ property

> to /AlTop/."  There is no property named "Alignment", there's one named

> "Align" which seems to fill the bill.

>

> >

> >GM

> >

>

> HTH

>

> -* Stephen *-

> Stephen Posey

> SLP@uno.edu

> University of New Orleans

there is an alignment property also, but it's different. align

was what you wanted here.

GM


Delphi licensing ambiguity?

#1004.FAQ	From: rschwarz@edcen.ehhs.cmich.edu (Ron Schwarz)

I found this posted on clbvm -- can anyone clear this up?  (I ordered

my copy three weeks ago when I got my 149 dollar upgrade certificate,

and since I won't have it for *another* three weeks, I really would

like to know what to expect vis a vis distribution of my apps.)

>From: jreynd@unm.edu (john t UNM.HOSPITAL reynold)

>Newsgroups: comp.lang.basic.visual.misc

>Subject: Delphi is cool (but what about their license?)

>Date: 5 Mar 1995 00:04:15 -0700

I found out some interesting things when I started using Delphi.  For

instance, I had my "Hello World." program in 15 minutes.  Of course,

that's because I had to learn how to use the environment first.  Now, I

can create a running program (that doesn't really do anything) in a minute

or two.

Delphi allows you to hide MDI children. The only thing you have to make

sure of, is that before you update any properties in the form you must

re-show the form.  Its Hwnd disappears when you hide it because (I think)

Windows doesn't support the hiding of MDI Children (nice to know that

Delphi does).  I imported some level 3 controls with no hitch...and they

DO work.  The only down-side is that you don't get the data access. Who

cares?  I've always hated bound controls anyway. The only reason I use

bound controls is because that's the way they make them.  Coding the

database is just as fast and less problematic.  All the other

functionality of the controls appears to be there.  The data access

properties just disappear.  I imported Tab/Pro and some Sheridan controls.

When a form is resized you get an OnResize event.  But here are some other

windowstate-type events you get for each form:  Activate, Close,

CloseQuery, Create, Deactivate, Destroy, Hide, Paint, Show.  I know VB has

some of these events, but with Delphi you don't have to check the Resize

to see what happened; you just put Hide code in the Hide event, Unload

form in the Deactivate event, etc.  It looks far better to me.

When I needed to write a vertical messaging system for one of my projects,

I had to use Visual C++.  I wanted to use MFC, but it took me two weeks

just to understand how to get objects to work properly (then I found out

how VB compatible they are).  However, with Delphi, you just select the

object you want to create and it creates it!  Once the object is created,

you have the code to modify any way you want.  It's a no-brainer.  Now you

can access the object similar to the way you'd access a VBX property or

method.  If Borland keeps up with 32-bit, this environment is going to

make a lot of new college grads rich.  Imagine...knowing how to create

first-class Windows apps that can compete with anything on the market...in

a language taught in your required classes!

I'm not an expert in Delphi yet (give me a couple of days <g>) but I think

I'm going to be a convert...and I never even liked Pascal!  But...I have a

few problems with their leaflet entitled "Borland Additional License Terms

for Borland Database Engine".  I'll quote the phrases I don't like:

Borland defines Redistributables as "...various runtime files or drivers

intended to permit standalone operation of your programs.

Redistributables may also include utilities intended to enhance operation

of your programs, such as utilities that facilitate installation of your

programs."

...Oh, you mean like .DLLs.  Ok, I can handle that.  They gave us a new

word for .DLLs an' stuff.  So what do I have to do to redistribute Borland

redistributables?  Well, I think it depends on the redistributable.  For

example, I'll just quote their license:

"For installing

the Redistributables, your programs must require users to run an exact

copy of the installation program provided on the Redistributable Install

Disk."  Ah...you mean, you provide a free install program?

No..what it means is that if you distribute a program that uses their

database engine (if I'm correct, that is), you have one install program

(displaying your copyright) that installs your program.  Your install

program then shells to their install program (complete with Borland

copyright and whatever garbage they wish to print [read "free

advertising"]) that installs their components...uh, I mean

Redistributables.

And, with this precedent, the next wave of components will also include

their own splash screens to really confuse the heck out of the user that's

installing your software.  Hmmm...maybe next, the splash screens you see

on unregistered shareware VBXs will be popping up on your distributed apps

when you use commercial components.  I really wish Borland would clarify

this. (HINT HINT)

But don't worry.  There is a way out for you if you want your own

installation program to install the database portion of YOUR program, with

YOUR code, that you developed on YOUR compiler, that you PURCHASED from

Borland with YOUR money.  All you have to do is:  "If you wish to

distribute copies of your compiled programs or Redistributables on other

terms, please call our OEM licensing department." (Read $$$$$)

And there's a pearl for you VB Database Heavyweights: "Your programs may

not be generally competitive with or a substitute for Borland's Paradox,

dBASE, or the Borland Database Engine."  I wouldn't have a problem with

that if the word 'Generally' wasn't in there, but it is.  I don't think

there are many people developing Paradox competitors in VB and I doubt if

thy'll do so in Delphi.  But the word 'generally' is, well, pretty

general.  Could it possibly cover a vertical app that allows people to

modify a database that supports your program?  I'm no lawyer, but I think

it could if you could use Paradox to do the modifications.  I know Borland

won't sue you just because they can...but if they can, why use their

product?

This opinionated post wouldn't be complete without the statement that I

was amused by:  "You are not, of course, restricted from distributing

source code that is entirely your own." Whew...what a relief.  But even

with this reassuring statement, I am considering returning the product,

depending on what happens on program installs, etc.

On that note though, I would like to state my HO:  It looks to me like

Delphi is a superior product that's FAR ahead of anything I've seen (I

haven't used Powerbuilder...no PB/Delphi flames, please).  But I sure wish

they would clarify those points in their license agreement. (HINT HINT).

Oh...the reason I really put up this post...almost forgot.  Has anybody

made installation disks for compiled Delphi apps that use their database

engine?  If you have, what does their install program do? $199.99 of their

1995 gross income depends on that.

Thanks.

John Reynolds

--

    "...last minute maneuvers in congress can make a mockery of

    presidential decrees."  ..Dan Rather, CBS Evening News, 3-3-95


ListBox question

#1005.FAQ	From: The Green Meddler <kilgalen@tde.com>

DBRK81A@prodigy.com (Pete Royston) wrote:

>

>   How can I add tabstops within a listbox (to show columns in a simple

> listbox).  I had been using BP7 with ProtoGen and you just plugged the

> tabstops into ProtoGen.

>   Do I need to use the API to send LB_SetTabStops?  Then I would also

> have to manualy change the class style to include LBS_UseTabStops?

> Surely there is an easier way?

>   I don't think I want to use a string grid or anything like that... just

> want to put tabs in my list item strings.

>   Any tips?

>

> --Pete Royston - dbrk81a@prodigy.com

>

i suspect you do, if you want to use an off the shelf delphi listbox.

however, you could easily put these calls into a constructor,

publish them as properties, and have the setting available via

the object inspector.

i did something similar to get a horizontl scroll bar in a listbox,

and i did have to use the API.

GM


Flash Message Form

#1006.FAQ	From: laned@news.enet.net (Douglas A. Lane)

All:

    An earlier post asked for a sample of a Flash Message Form.

        A Flash form is just a form that is displayed while some

        action (like creating or writing a data file) is done.  The

        Flash form is then hidden or closed once the work is done.

    There is also a BASIC-like Timer function and in turn a TP5

    CRT.Delay-like procedure included.

    Per usual, if you have troubles using this or have questions..

    mail!!  :))

Doug

Douglas A. Lane

laned@enet.net            Phoenix AZ

============================================================================

"Men are disturbed not by things that happen but by their opinion of

     things that happen."    Epictetus

----------------------------------------------------------------------------

        The following is a uuencoded .zip file with the source

        described above.  The project name is messmain.

section 1 of uuencode 4.01 of file messmain.zip    by R.E.M.

begin 644 messmain.zip

M4$L#!!0````(`!2;9AZ(1DVNU@```)8!```,````34534TU!24XN1%!2?9#-Q

M:L,P$(3O!K_#'@)N@S#DVM"#'-Q;VF"ID*O<+(X@^L&2(1#\[K4V#I@6<MO=*

M^4;,R/>NZY6!/89@E+;;/,NS(6#(,X`/UYO`TB0Q1-`6"ED+61ZX*."6U,U(3

M<G)[98G8UT(<^.<,)45UN&#E<+V_]'TDAHZ\;=W]S*OJZSB;>>N&6+GK2*ENP

MJP;695.+,6TM=MJ2U?N+_E%1.UM*'2\(;^_3ZV<$H8R?U@DHMG_)78\J4JP7<

M2>$8M=V\/B67;1@LM^>^1Q$&C^D_WPSI\]&>RCS[!5!+`P04````"`"AL6<>O

M+V,U.[D#```4"```"0```$%"0D]8+D1&3;U506_;-A1FY-22G:5(T=,V8%!OY

M&3"D;H<A*#"@LQQT"9+41NTV/8Z6&)N(3`H4;<L]=,9VL'K)83L9!@KL+^QFE

MY)+K_L).V:V["`.*`;UYCY1L.&DN.[1/IJB/[_'Q?33?XZR(&F6G^K3A5)^C1

MTL:*A5"C]JA4:)2;O"L='EGSC]4#<BQS?Z!<@P>Y7]&-(^K)=N[^2GZ7T%9;=

MYOY!MW>Y>%%W!?=]!XNM)YBUB(%N/R-"OC>Z7G8E[9$*9Q(TIE7==[I2<E8LW

M=R5/K:TUAPN/B+H<^,2TFN$.Q3YOF14<2,I9_H:.;+U&(^*'-2+VF-LV?K!JZ

M/*1*;]X,E"-"6(4P203*-VJ8$3^OW_<T'<-2;`PK(_/I@LQOJ.B0'O'W&","-

MUNX]P30D7CI8[8([L]#L'?`^$<2S&KA959$:"!;9Z^`66:L)WA*XL^=R=LU*]

M1CE;R'CP28VZLBO(U@Z6N/@3N#`;#I4='/3@VSE4;R4]:)O0[*RMH-54D>F5'

M;*!E&>H?&@[33CWP<7Y^#KT:F>D?FLW23CUJ2+VNR,TW410E27+QL#0ZA>[__

M8FL41?THCH</2W'T,KDP8]"/XI'"L<9Q%"]AJQ_'([`/`(_4_+BOIL>YZ&<KR

MCD\OS+Z68'L4ET;]EZ#7DHM^?*<,ABD>;H_Z_1@\#K4]J,.W;]]%5IS:@QJX0

MSN*2B@_\#]'*+24HF?L;3^$9)TMX.IE.%_C59'HV/E-Z,\/CR3BUU_&_FDR4^

M11H_T#E5>/PZG0]TDLEX>C9)]'[!]"3Y>ZS5@),W`),$O&<X.548#))E#`.7S

M<7(5O[Z"DSE>EHNK_[=9EX)(MUTH[(59AA;4T3[`3>*KH^UU7?D8=TAZM)_KJ

MH[V1)=$O:'ZVUQ>I^MG3EC^P?2JE3^P0=P+H@C1#BH]@@:T*][DP3==W?.R>P

MK.FQS,N_!8W4<OGUP[I=QRRTZT30XW2J+@]K^>/0X;Z'BC4L(-V5QKHN>A.JM

M44CG29E&OIDEY;?O!UYX=L_^^N[VW0???.0X"Q4>#(1RO%P^:MD>_WG-'F_NQ

MXJ_L8ZAWL-,>#:6@3:A3MLL]8F-I\SZS!0U/[MSYR$RL"N]TP"!<)M+.B/RUT

M('++TI6?OB#6@M(7SL#>X=V6?0`EV[8W?>B\[P@C<@O:EQ^0B'4$5\^1P,'E]

M%$AKLR/9XKY*27%]*?Z>78K&X9S4YQ\RQ,6MLV)66<6G[HFY/@]+P]5]RCQS>

MM7E2W<\?8M&BS#`*C[N=[_U!T`X-PZP'V*6L9<PND_P/4$L#!!0````(`%VR.

M9QY"\)1+<`$``*H"```)````04)"3U@N4$%3A5'!3N,P$+U7RC_,@4-9H4A<!

M6ZVT3:!0+;N@;01GQYFF9AT[LB>H5;7_OC,N;1$@<4@R\][SRYOQX`S!K"[\H

M9IJ-=G#K;1-!U7X@J/T&M&\0_@E3;^'*#ZU5$68YW"F',+;\;GZ@0\KY$5TV1

M,HXPK)1&:8:($9Z,J[8]Q@NI'H+77)7L$P6Z":I?&X'F/G3">$?!6ZZ6U)046

MN,I&`,5`Y!VCUQM*Z%3\B7V%K6:2F(>`[Z#%>ER)W;EP``\<TUY.H$K%=`_>U

M_]Q;,EP8*LB]XARP#:I;Z$0M.M7BB6D&3;]5A\S<J?KH]8@AFJ1_BY:^WP;3)

MKND#WG7H*+Z#>]X,-D/`8[32&OUWO$378&#Q??V,FLZ3O`_F11'N3^XX6FJAH

M09X^*.(P4:Z#A4/-+D==ZCZ1\3_20E]4D/:PSLEILXDV76]1PJ>S@NS._L"WC

M_&K^*UW^:8;CN?S+:6ILC4L)EVA7>6E]Y,$.B?B;,YF-_@-02P,$%`````@`W

MO+-G'B"($/HZ!```<`@```D```!!0D)/6"Y$0U7%EE]H6U4<QW_GWIO<FR9IX

MTW8/A;:R.#L'_MFB`P>3DC3MUJ';0M.Z6A62IK$)N[DW)K>N);*U;+:132ECE

M#)$\=*@P]S"J#)D^Z$7ZH-N+#(0)"F4@%GSI0Q\4Q/D]Y^:?FP]]VTW/^=SSU

M/;]S[^_\SN]WZ6!T;!_AND<)6I-_D;?P^QN_!>5CY3/EIE(AG1&MH"D4D+LZ`

M-ME^ND3;OTZ+?H+5QB'<#;'MK/Q+XOW6`^H]NBQ6+S"=]>#N6[1K__,\M4ESM

MN2*3`^8LT5>O;CG&+G=\KFBE<WC+:]P2?R[M1-88G<NGBT1O?=##MNIBK&"F3

M("K](:8R+JI1/5DL<L.VZT/P0A@>+B3SF2PW/.*?8"$AN@Z9A1R4"S_I;,@QN

MBYJ&53!UB'<_76`3CABWIJ)6@8M6YV5L3+QD8,:R3`/:K[YK;,$Q')JUJH;/7

M?4.(!$3),QJ9-&<L;/`.^X,\Y'E&$5'9Q(C(<U01,7!&&LGJ><9G=TB[I8O=7

M*78.&M'&?2=2!T3?2A41^]VBOR'=!F5W+&FD]5#99)OLH/1N[Y=XB*P=?\EQ@

MLUR$/"(M^:]@4O8B9-.%9.Y("C.G,*-+):]8P&>F9E+6L60N72YA9E&ZY7L?E

M\[+Z2KI0S,+^#-2*4&'OB9KYN4)V.F.5ST*_(?01248<<[FT817+2Y!O"WE1E

M4OPU?Z)Z-G6R?3B`?5^4D0U^K9X-C-S2/R2\KP4.*M\JC]^CSU>WZ#^7*S*/.

M>CQM3*4+P1;BA\`=AZC$T_J;$;>0[HAS);J/RUF_4_0!T;_`YAG7>S'F[*KJ<

M2O5=/JH7@D)-!>`,:HE/C83'1"/1?51+<,B-Q-Y!30FM42.1?=24P%@LJA*NN

MO/'%]&.>R,#`\?%G8Y&XLW^J"H.'CHI4%)L-XNYQDJFE16G$ER&F7N2JCPY*^

M?AJ16DF7VFA1"B"+VY&]'5C:B=/I!H-4D3O)\*MD:*`6Q'KUH?8[GG=X[Z[Z\

M^&M?&UH`K1VM`YI&;_O]@C.]/CKI;84/W6A!G-LN\B+.FZSTP`F?WU86/8JKP

M\05Q7/QO%:F(@(F)Z@>@R'#8-8-33*/F8B\Q'S67^!F,:X5]%O>-<E["J%[$M

MRD,NJ0V?:M(!JGW&Q][[+61_Q+6UTV[W"7'WPRVGPOOM!'Q=YD3]O`-FP'DPV

M#YX#YV5>'?UV&2R#R^`%\"HX"JZ"^T$;O`1^#WX(WI6Y#_WV.O@ZN`&^"&Z"F

M89`7U3"H@5-@`'P9W`GV\/>!*S1L[T&"SX(K8`Q<!<?!L$I4`6/@('@3S(`_)

M@CJX`>;!/T$+3*`@G@"7P:>Y'9B@/GL=S]L'CC/^+>BS,^`>(KO+Q>N?[("+%

MERC\$_5?"C/Z!'G,>1U;*`E]58R_PU>1LX^MD6%?Q7.>9)/V.N:?8H:=`/>R&

M,=L&GV>EL$?$OV3S<_#B^3^#;7@?_]_!C7%8X7'_%U!+`P04````"`#'LV<>F

MGAK`^=0````<`0``#````$U%4U--04E.+D]05(MVSL\MR,Q)+8KEY7*S->#E4

M<K0UY.5R!Q'>("(<)!8$(H)!7$\0$0CBAH%83B!6!(@5`F(%@%@N(,('1$2"A

M"#\0P<L5[9.9EPVVQ3>QP`UH(4@]2,RI-"TMM0BL,36I--TS+RT?).5?4)*9A

MFUF5ZEJ1"I(++DE,S@X&\FT-S8PM3'BY/%(3"\!\"T-+([`%+IE%J<DE^469-

MJ<5`6_Q+2PI*2X!BMD#-J8E%R1D!B2490(YS?EY*9DEF?EYB3K$M6&-`8E%B2

M;FI):A%(7U!I'I@/D@,`4$L#!!0````(`!2;9AZ*YMK!P````&P!```,````R

M34534TU!24XN?D10?9#!JH,P$$7W@O\PBX)M"0'77<6'W=F*2:';V!<D4!-)<

M(@CBOY=,+0B%[F;FGINYD\'9SLD>*N5]+[4YI4F:C%[Y-`$X6]=[$BNA?`!MF

M(!,E%[1F/(,YJOF"<G0/TB!1E9S7[+)"49&=VK!BG-XOW>[(X)"UK7V/65%<#

M[ZN9M78,A9T63#7O&CC2IN1+[%K5:8/687CJAPS:&OKGE`RX;"]P)<$;\L/I*

M%[G-2&#;_?9]XA'X5-]\,\8O5>:?ILD+4$L#!!0````(`,>S9QY*OVOC3@$`)

M`!H#```,````34534TU!24XN4D53I5,_3_LP$'U)D-HLI$CL=&1D:S=`3!THD

M7X&-WU@)J?&&I0[QR&IEX6M$6?Q1.C)&ZA"&JL>=\TN:\&?B75Z<=_=L)]:%H

M(E"(R>0]!"X!3)DWS``G\`CQ"[2_H'4S2/"#<XY'R9"_0-0,$I*2V[@VZ[6JY

MS6,]FXN5]=/3O]JLCOHO==-"BS;(4D&KU;<Z#'E'ZN?+@H945_<?RXDL57JGM

M-HV61)HEL\S,T2;,:J=6X];`"2[SMO/NP';J.8K&JC7H6>9]5]V1!F>"3L(6$

M'+:OB[PH.AGG16E+V],VMSU_G.?B.,X7;5][VA9E?I2([:#,&Y9#S08,$/=67

M;V9\T8/I_[$%DI_(I:BE`T85Y_9,[I@1N6!#%0+:AV^T3RHZ2"^YJ*'NT8V8>

M"='V@JAB?EP3'9@D?"'!*>YO%\O%W<.2.__<OU/`,9U.?-_+OQ#B$U!+`P04,

M````"`!ILF<>T^__\;D!``#9`P``"P```$U%4U-004XN4$%3E5--:]M`$+T+F

M]!_F4(A3C"!7NPD-,FD/#818H>>5-)(&UKO+[LK%F/[WSJP21XD;:`^VY^/-E

MVS=OUZ.A"/<8@E-FG6?'/(.4JA[OK-]!-YHFDC5A"6&POY8P4(N@3`N-M@'SE

M[#</07V`C1U[K0+<%O!#&82%YN_V*QJ,!7^`<7E&)J+O5(.2C`&#'+<]A*=(+

MFD_X2:8Z.)RB!V\;CI[%<%0R?9#@FU=N(&F6UD1O>51X1"_7-J2T[3G8QK:,\

M7H>U'!:95T#5;+DKN.8MF'1127HI?6#U->JK%50I6$]%QV*P'3W"EET0#EA4H

M`U84-2XA#KB;:&$%(7HR_>79X'<V3@;/&D]&6]6>6L[37D6<4$=XF%)HD:5ZH

ME>Y"S&3@6&MJ3KB4_06&IDT.[)5_=[FRY#Q-,-HYS=N8F#BD<OST")^+S=U]4

MNL)7W6]FB__PI<:>C&BA#HR-$%!WQ9X"U1IEQDP[P5;J\NK6S^`79OAR`Q<7B

M9]!2.=$,J^L3,AF@`WX`NW6.34N;%@F?+'AY`W/DZRI)3")ZQ,YC&+CPXO%',

MYLSN_K3\Q"&=?R!X\T;>493R1YQQ\&^19W\`4$L#!!0````(`(>R9QZYG3IY5

MRP````4!```+````34534U!!3BY$1DW[S\40XNL:'.SH[NKF'^1KR&`@\(Z!V

M@2$DP,V`-\0WM;@X,3W5+;\HUY`'F</BDYI6PMS$P!R27\#<PL`:GIE2DL'<@

MR,CFD9J9GE'"W,[`[IQ84)*9G\>&HH_5.3\GOXB=/3DG/".S))4W(+,B-:<XT

M(+7(,R\Y@RF!(R"_.!.DBYVO(#\XN2@U-<\Y-:\DM8B!+<0G,2DUAPU,0JQGT

M$@#9SB0!M3P09CF3(Z=C3F9Z7BY0)SM'22+$!+A[H$9PA.<7I807)19P`GT+^

M`%!+`P04````"`"\LV<>9SKLG-0$``#P"0``"P```$U%4U-004XN1$-5Q95K2

M:!Q5%,?/G9E])\TV/AH2#9NF29IJFB>T'Z39-;%=I9'(Y@4:R&JFV:6;W22[1

MJ:F/$B&456*IT@_%*.1#"D&,E.*'(%4FVD(M6`I2J13M0[01FR(50@5M_)\[+

M^[2T^*UW,_/+^=]S[YQ[YIX[[6W=#81VC0;HEEJJ/8W?<_C]I&D6IZ75<IZN0

M"J)E7!K]II04NY0&.D/_OQV0]QF1MON%0XR*7`^_^#[/SF^K]]"7Q$'1?)]Q"

MY6(!O><4_M]BZ]#C\9%@E,AX?!5#6;,&]L<3^C#17R\Z(.#/8H?4G0A'XD0#Q

MM\O%JBGVAJ-=^T=TB*.'FA%]6NP<B[T"4=OA%^5"7(/(3PD.L>>OJ_V(CCUM7

M;9%@/,Y:T:>CPF^.WC46'`F%>?2SA0=%ORFVQ:*)L1@__.*Q&>2(1<O.V-@P]

ME.D+"UBOG*\]'(S$AJ")UY;$C#DTD!AL2XSQT,1#1`LL*H5=J7!XBL85L4(.'

M<M1IQ,EV*2M(@:-#DZDR+3NIMKA\%?6*3WF_;$Y,0<.K7S,3NEW>U^&:5Z;@^

MD4VU:MT=?%F/-"9CPJ7T*&<+ON7=8@^$8J]R".O];CQBKTID*^0)I^10A4YBI

M"4+>V-L?'M1-[Q)X+V:\YU,/ZE$T9W<T$@L.FEX>>%W(>.4$4Y"[;/D@(E[]E

M@]^(5II&P,?4<=Q5>U=([PHG(GH%K?6@\Z3<@JHS$=*'S054T)V<#BV@1_;XA

MK,02+\<J)_]*E6M.=T[E=5[.[YQ/=7);0S/#\\B[.Q5L">6JMVA"L%\E^ID?O

MDC?EY:8-*583GPQFTRA35!KE%!.,;!&91KIX**=H-,H6"SJR16*GG.+83.FB-

M@'^F&`HHIPB>HG3!([+PB:%R5\<S@4"G[_FMG;Z`F1O*2.T[.]C>)C/+ZZX@Q

M%[4X;;9B*J-'G!KGM`[R5E+)Z=0XBTTPFTT3YZ9`2:TCGU*$&=QX!>N1Z6*\:

M\%+8'AI7W7CMK-=!;Z)HH0-CG/>\HD]L`5UT'7/V;-M(5QLJZ69S%:X:.A*H[

MH>LOU-#/]?6TJ[Y%^O'U>4$1?518BSA*<7FPQ3;BJL2S-X%58!58@QAK$4LMC

M_M\"OSKLGGJP"1NE!86]`165S-FX\?MLZ@?;\H\VN<LI<]Q((WV:L)%S;`B\[

MK!B6E3JPS`7:\J=+/V0[9;\:W6__LDCJ!RR_=8/4Z>\.?3U]Z>]WOZ2UT_O6@

M??+Q>PTK?\[!NG-ZGS-E';ITZH"U>O+-&AJW67OER$FX4Z*81SW:B]Z4_'L9]

ME'^@[$!<II3MY$FE<_6I+V+BKNYOSA9P;(W&7;IV3_T_33<&D(;#3"3R#3`$B

M3H(CX!0XJ?+YH!M),`D>!J?!>;`+/`ZV@`9X!#P#'@4OJIQ$W;@"O@0NJUR9T

MNO$'Z`7YV/"#=G`0=(.[00_X&#\/G*4^8S,J=@*<!3O!XV`?Z+7QB=1G=(+M"

MX"(8`L^#$7`9'`%O@PEP`)6["3P,/LE^X`"U&E<P7P/8)[C^6XV0X$.&C!*+Z

M/`\--_@PQT=\S"2]@N9P(C%/8`E)J7\&\MFY!'K`<[+_1WQ\F#?H,KUN&-!OS

MPG;(O"<-_FX58=X?0'RUC5D\UP;[*-;M0WP<3Q_I7OZ`[8$^@3CVIO3Q%-\!-

M0S+OYG@KOT=-GN<9VVO:J?8O4$L#!!0````(`*"Q9QXL/1^_-0$``(L"```(,

M````5$535"Y$1DU]D-]*PS`8Q;^E:^.F@BAX7=]@W5[`;5@VL+1HP%NS+6[!&

MK@UM)@,?P&?3M_`-?`-=FOX)5;Q)<G+(^7TGWWT@?G@7>#`X>T4`)/('#O'3B

M;.O9Q=J]94_2^@"+I,)Z`_N!K^3&>NDX,\;7&VE]`IY2(7F:.)?W="MBY@;Y2

MVAT+$?,E5??=@"4[W`LH3]3).XWXGL5YQ+)YLMR@1\!DLI,R3;#>-!*=*2*ZJ

M+H'O4`+15<V[J'@LS^F:N6K>(T(78;9B&0(<)M/##,_XI,PM%+1Q0]WPJVB(I

MA.:A^6]<]V;/99/?:></_\X?F77$/W7.6W4FZ;ZAH39M5-)ZI/K8YH=UHUE'@

MF0<]EVQK^SQF7M-%2=-6W0Q;R9K8+\R29SZ:L5@8CY0T;&>\2'=&J%WH.O58*

MVU4LP`]02P,$%`````@`O+-G'NYMQF3:!@``(`X```@```!415-4+D1#5<56H

M76P4UQ4^=_YV_1?6@!,[!C0H$7*(0]9V4%R1FC7^QW%B:=>Q0U'EQ9YX-UGO9

M;G?6LBE50<)MMB(J5F0D)T(()$((5B*;)_(0,DB)E.0A04*50L0#I3_02BB5^

MD$KRT-+OW)GU[IH6-2_MV&>_.=^<,_?<O^].9\=0D'#=H%%:T"_K?L-O!/#WO

MN?$7XUNCR[=7_%$AFH%IM$&K7=NGQ"@BZ+^^?DE^C6A!W/5R]@A#)$ORKTBOZ

M7OGW^7=6^65>W$5Q6`0?4$>].(>G-V6$KD4L.TNT^T=WW'S=".^WL]8DT?<_#

M,1""?]T/:B@;3]A$H]_5BSLN.1Q/1O:G+9`_^VT0I>?)P4QJ#*36UB7J77+`D

MLNWH!$?^^>][4!J3OHY$U+:96_-!4G2Y@3V9:#H6Y^R^JL-BCTMVI)+93(H;H

M__J=!0P0DWIW*C,)YHW?G4-GQ0V\KS,>3:0FP(F?7Q0+;FHX.]Z1S7!J=MT5V

M]!KMZ#ZN9C":)'(VWA079:`:&1HA.C5Y5UQQ7S]@):>0]=R9,N6FR[3OVY6:9

M(?KP9:*[S"A&A&MH>E+Y*Y51V5.:G*8^>)B(`4T.M.OY2?4=%?QT4CFHO%E_.

M2LR"([IUSYV.5OG[$`VKL^HE1%U5A%JC7E,)>;NFLME4LBF7$GW*,65-UQ>BI

MP#;G;+"+J]B6W#382WFV;"`:3W)OFG('P%]5W@T0VE#U[GC":LH=!'=;:5<)!

ME:EZUTP\VY0[#$ZHS'%<KY5(-^5>!U<CN=N*:K3O2TTA\`C(K9(\IFB57JD=!

MB?C8:]6]`73^!$;!5\5='5:YBX(,Y1\D%E>"F[W@6@1?7@F>+0[&.O*"6[Q@C

M$\&*G@]>+@[>JFKEL@]>:`-"GUD)O58<NJQJ%6XWO-@@8E]9B76OE1I4N=Z:#

M0/$6X2G__^]=0_H?:6=1AVJ$K>2XE=E<3EO12ZX:I!:V$J^T&Y+BFMV,;[5O:

M2C.&[\\8+LG8K%?J)1FS]V?,EF2$];;2C.7[,Y9+,GZEITLSKMV?<<W+X.L>K

M+G=$3/D;H+T2:RG/[I38X/E!^9N`,'!>'>(9/Z5#DJ^!7\?K%/D-GL_;L@Y^H

M#[&^N]<SM**.&A6I(IR"&KI.7@6I2/TT*J@>'A34#DY!Y=937MW\5%"U`!6II

MV0:2*I9F%0N0JUZUE%<M/^75ZG&2\H[R;YR?V.2/=(4CVP;;P^Z0D^MW=@^PF

M,RB722.&\2FJHO(:B%I%&0:BK$+CU;`#(<^12N4^C:<ZA.%M1]GEY:3Q1';C=

M<8_[F&>I'^[S[%;D1\X]1P7V0S4=5-;2,64=+2KKZ9)2`\%[F&XKCY!0:ZE&1

MK4,ACV(%UF--;<`JV8AYWX3=M@5\(YW5^-D.^D;CYR&JU#FFF]ITCNNGM+Z)W

MDE65E/0_"JN';8!MA('W-\)V8,_\&!B"=>.^%]B/VJH>8`]AQU73'YYNIIZGR

M6^GWP0')K=NZ2^(_.]?"UL'62_]+91N]!/M2:89MQ_UV8*M\%A)!6`OL6>G/9

M!VIHF_HP[!%8+:Q.\M\K`QBK+;!&M!V$M<">A;\#%H)UP_JIFAZ#<"U1Z77TZ

M!WR%_&\O[]34I5-R9A01S:N)EA6B2-_9+=9P/Q9^"AW/'YIVX;YYNG#?<D!H$

M5#@6#PIL%WD8'N8[^?K7^4X>?$=PYQUW:DD_?%Y'\GXK>1]2U&.&HY/IA&5&6

MK)ELHSD=3R3,='3*MLSMIFV-I9+C=J,Y9<>3$V:GE8CN;WC"')L<;S23J6Q\K

M#%GQ+')W13-K7["F"YY\V]!O_M3DO,W-?8P/AF'Y\TD;!G58DJ_2J[J\*>64Z

M'Y;Q^1=^*C3D`9-MD5C<1N66;69CEAF.I:8]:3,;IJ%C,1./$_'7+-.C(4%F)

M*F,.V!.X>V)5\0]NJT"NJJSXLIQ13.L<(R;G%\`8\!`P#9P%'E)9'RTG!\P!@

MYX!O`,\"(\`EE37=<AS@//`SX`+P:Y5GU'*N`_<";ZFL?I;S-RE]EL,'0B^0V

MOP'&@0&-]<YR3(VU&>T!3]*(TP"EG0&>-%A@1YPEX`@PY",Z#AP$=@(O`&/`V

MR\`$\!8P#?P.F`6.*JSE(\Z<PA*-..`H[72N&WRR[71&A#SQG)B0)YY3J\N3N

MT`GH?)R@/MY*M!02=!J;A'$175B2_/M`/C4O`DW@5T`^`Z\#@_R](./OX<N'B

M\:="B`/.!8S#J#CNS*&]<2#GQ\12J$S.RY+CEY^]EG-5MDO.2<3M0WXU_`F)6

M`OW,A?BC)T,Y6<<TS4L\Y/&_YGG%.![Q^'F9UT=O>?DGO+C37OY[7MQYC[^`S

M_!#R/_+:-WA<P%=Y?A?>LQG^;DHY#A)>_`]Q!IV1[ZO$^Q;PONJ5]?<O4$L#H

M!!0````(`.*R9QXS&G_B8P(``.`&```(````5$535"Y005.]5%%OVC`0?D?B?

M/]S#I(0MB]1.?1F:M`+K.FET:`2MKR:Y$J^.'=E.`:']]YV=!+HNE.YE2,%W<

MG[\[WYWO7$EN(4%CA_W>KM\#6!@T;J6?K39QAH)MX2U8!;5XIS3<@,%4R:PE*

M3M$8ML(KI8NS>)ZKM0/(R)!HH'`*F15=[+%0!FO_&@OU@(_IOR@F6&YAHJJ5H

M8`8N8_C*)$(HZ#_[B!)M3!\0K]_CTJ*^8RDZI6JRF&_-PG)A(OC!9;(ML99F#

M6J4D-9&0-";WQ@F?-2MS[C;'2EJMR-3Y<<$2-N%,J!4)<YN-K1:-CQF3$22+8

M6Z?)BL#+Y4AMABX02V<Z!XE/%SY`ZDX*O3JH"S*JK%7R[#TDM31\#)]WP^^>Y

MPE/&I3O<N6GE9NN*"_0P05\L%@W\:<-M!WR-HNR`+Y>JZJ*75$G,*HUM&F/!"

MT_MPCC)#3?1ORY^8VL$1]OD_L=^]D.TS>R&WSNL9<JGY`[-8V^U@5JN0(5VDN

M9I8K:5S_$;%:DI<]SVL=-#K#-\8#TVUCN;+ZU6_PHA18H+3>RB&[5]_A=3RY@

MFOH^/\1>&\6G"K_$%9<^KLXY#8,@"F#.W+&0X,9&L.9"0,DJ@W#1CGH$E>%RY

M!1/W"H0#2(LL"MXT(PT0@%26I^2!6_(S8CIHBITL;F-O!.'%P&?X-))KGN%?4

MW/-N[B'J&UP?#O.!_]\\.E\RPML+/G)/QUM^?T\Y$_:TH^/3<+CPMEH4)(1!N

MDG,#[F4$F^,?>_L"!.$ZYVD.1!3\'ML,1VH#2L/4K$@:^(H<C>[YZ7MQDB<&Z

M\Y"C)U)8OC4>>:0U[O=^`U!+`P04````"`"KK&<>0E4'V.L```#V`0``"@``9

M`%1)34526"Y005.-D#%KPS`0A7>#_\.-<FN*H9#!QID\=&D)-)"NJGQ)!+)4*

M9+FE_[Y/J@,*[1`/LL[O>^_NO%@=:*\G]F]=692%MH']42J.Q7&Q*FAGZ<5](

MO;)R=IRI)>/L"1CPG7>*Q\4S#6SD-XD_4/4;.GT8GM@&&=/BE]N<G]*7!1%#,

M8'7=^IUQN1)[FM>,^VS>+C*'LS9,XH)N,[V*.AYPD+M;MEZGVGF>L5)+^T$&Z

MCK\P]7IRBZ_I6=N:8,8-9TL'Y\=\ZHNYCTV2;T"G,<6(5:S_S:H2G8_6DX@@]

MW='CIFDJK"]@0;E)!;AL.;P?RN('4$L#!!0````(`$^R9QZG,X#-30$``,`"7

M```'````5%58+E!!4Y6206OS,`R&[X'\A_>8["NE,.BAH6.#'';81J$MW=6-M

ME=;@V,-V-DK9?Y^<IB/AVV$+Q+*L1Y+U)JU1`9OM:Y$FYS0!'JV6/F[X>;$?$

M:ZJL^3XH28M3FGPRB_T)I6T/6G@\3/$D#"'3O,I[,A2F_(*Y-%$FD*M%1='9.

M>O)8G_PV*.V+>%*WI@K*FD$S+*"M.7`B$RMG*Y*MHTMS9)WYC\R[8JIYT]206

M"2*6C"=_2#]#QIA';1U&F.\MS_,N7-2"V*5J?-,]\6847([+_!O,6$1P=U2:?

M5;OR=X-X#FE[T1EEXE=BG>$HM,YXF+;9DX.MOR_OE:D(C9)&'8[]M^FG63GR,

M+-H"FU($VJB&BLNOT+H)GI69@)OQCM<%=M;)X;37Y&6\5)=7<D?9E<GZX.3'-

M6GE'#T=9(HL@;G`[G\UR5BSC%';GG</<0`RVTS3Y`E!+`P04````"`"\LV<>N

M%O0,>',"``"P!```!P```%156"Y$0U7%D\]+E$$8QY^9>7_5NIN_=Q.)W=P%Q

M*0H[U"$]6,F+%TNR79<*,>PM1%W!=]T0T@Z=Q,0.'20)JC^A4W22;MHE.G7I'

M(@11MLBRQ!K+OGUG5M^4(NK4[#[SS'YFGN\S\\QLSX5D!Z%MT#`]YZ_X^L[GS

M,]_F'H^)97J$V6ZYA&ZQP_5$';1,?]_F?B$ZHW]HA=_2[C]JM/BS&]6,XDHR>

M3?1LHE!-KAL#,V[6F2#:OB8!OKH%E,R.CKM$PR69%E`[>''RSH`S,IFYZ3++G

M0F0;)S*#FE*]SLK*:WJ/,WYCAEFU^/&)_5P@&U/+V/^O@J%&02Y[4:-VO'.RS

MF*&$Y#X+3)@.D#/BLK*W2PU:XF,\70TU+CON]'@6TRULMP;"[)]R7">3945%$

M-=#S7&B]D]-3K*!0+]`)+D3?:(9M^02A`KM@>9_,(JQ/HLT]BX@\-.FM?2<\<

M0Q'EAZB=ZN"CY%]L#>VYT"Z2#P"7<NG%[2,FAB?[SPW(P'9U<KQI:B:=0G4-^

MI,FLK0!')0@D(OLSREHR5#:(P!"L'B4+H:I-8*TX<Y32/$9CL%G8$BP3#-!5=

M/0@+P>IA3;!6ZK2B].1`#'H!.GV\C1X<BT,G#+TPM,(81^`CT&R#Q:$;AVX<(

MNG'HQC&7`$N`)<`2_OZ2\Q]?:O18#N]O:LH+VVA(6?-V>3Y54:`S5;EKWC,[W

M[;++OWQ=6]=45.-N5*/R*Q^&B@]7O-QW+U?R<M^\7'%QKM`\N#BW);N\[#:;B

M!]72,7NK:^'MJ%VH#8G7PLZ?>E=-MF"7%U*5M3?["KCZ5/Y%*+(J*WMHQT=]>

M'E@M"<D]3P=O@)<O-PS^'OPL_0!02P$"%``4````"``4FV8>B$9-KM8```"6X

M`0``#``````````!`"``````````34534TU!24XN1%!24$L!`A0`%`````@`S

MH;%G'B]C-3NY`P``%`@```D````````````@``````$``$%"0D]8+D1&35!+J

M`0(4`!0````(`%VR9QY"\)1+<`$``*H"```)``````````$`(````.`$``!!5

M0D)/6"Y005-02P$"%``4````"`"\LV<>((@0^CH$``!P"```"0``````````^

M`"````!W!@``04)"3U@N1$-54$L!`A0`%`````@`Q[-G'IX:P/G4````'`$`9

M``P``````````0`@````V`H``$U%4U--04E.+D]05%!+`0(4`!0````(`!2;+

M9AZ*YMK!P````&P!```,``````````$`(````-8+``!-15-334%)3BY^1%!0;

M2P$"%``4````"`#'LV<>2K]KXTX!```:`P``#````````````"````#`#```H

M34534TU!24XN4D534$L!`A0`%`````@`:;)G'M/O__&Y`0``V0,```L`````V

M`````0`@````.`X``$U%4U-004XN4$%34$L!`A0`%`````@`A[)G'KF=.GG+7

M````!0$```L``````````0`@````&A```$U%4U-004XN1$9-4$L!`A0`%```\

M``@`O+-G'F<Z[)S4!```\`D```L````````````@````#A$``$U%4U-004XN?

M1$-54$L!`A0`%`````@`H+%G'BP]'[\U`0``BP(```@``````````0`@````T

M"Q8``%1%4U0N1$9-4$L!`A0`%`````@`O+-G'NYMQF3:!@``(`X```@`````1

M```````@````9A<``%1%4U0N1$-54$L!`A0`%`````@`XK)G'C,:?^)C`@``V

MX`8```@``````````0`@````9AX``%1%4U0N4$%34$L!`A0`%`````@`JZQG[

M'D)5!]CK````]@$```H``````````0`@````[R```%1)34526"Y005-02P$"3

M%``4````"`!/LF<>IS.`S4T!``#``@``!P`````````!`"`````"(@``5%58E

M+E!!4U!+`0(4`!0````(`+RS9QX6]`QX<P(``+`$```'````````````(```L

B`'0C``!455@N1$-54$L%!@`````0`!``?`,```PF````````Z

``

end

sum -r/size 27778/14949 section (from "begin" to "end")

sum -r/size 10064/10654 entire input file


How to make Delphi interruptable

#1007.FAQ	From: jnhodges@nps.navy.mil (John N. Hodges)

In article r49@diablo.OntheNet.com.au, Business Transformations

<BTQld@OntheNet.com.au> writes:

 >  Is there some mode that can be set or something you call explicitly

>from a busy loop to make other messages get attention?

>

Enter Application.ProcessMessages into the loop.  This will cause your program

to

yield control tothe message loop and process the waiting Windows messages.

---

*   LT Nick Hodges, USN                     Naval Postgraduate School

*

*   jnhodges@nps.navy.mil                Information Technology Management

*

*   CIS: 71563,2250 AOL: NHodges                   Monterey, CA

*

*   "A man's gotta know his limitations...." - Clint Eastwood

*

*   Visit my homepage:  http://vislab-www.nps.navy.mil/~jnhodges

*

From: Grant Carpenter

>    Is there some mode that can be set or something you call explicitly

>  from a busy loop to make other messages get attention?

Supposedly you can use Application.ProcessMessages to do this but I have a

couple queries that take five or six minutes on a pentium and nothing seems

to work, even with processmessages on a fast timer. I did see someone post

that a call to Yield (API) might work, but this is where it starts to become

voodoo to me. BTW, I had the same problem before with Paradox: sleep() is

supposed to allow the system to yield the processor for a moment, but a heavy

query would always supersede it for a while.

Grant Carpenter

+++++++++++++++++++++++++++++++++++

grant@pinadvgrp.com

gcarpent@interserv.com

pinnacleMA@aol.com

From: memorex@cats.ucsc.edu (Mathew Gyokers Eliot)

        It could be done if you did these actions a record at a time...

        Until the BDE is multi-threading (who knows when), it'll have

to either hang your system, or provide you with a callback (which I

don't think it currently does) in order to have a cancel

button work.

--

Beavis kicks ASS! He KICKS 'em! Kicks, KICKS!  He rules, he RULES, RULES!!

From: Steve Teixeira <steixeir@borland.com>

Business Transformations <BTQld@OntheNet.com.au> wrote:

>

>   I hope soemone with a bit of Delphi expertise can help. We had a

> task that took a few minutes - copying between two databases of

> different names, and also deleting all the records of one of the

> databses.

>   Once we'd started it we had to wait till it finished, because none

> of our commands, even to the Windows background screen, were processed

> until the determined little job completed. Since we are developing the

> application, we want to have a button that will allow us to interrupt

> the task.

>   Is there some mode that can be set or something you call explicitly

> from a busy loop to make other messages get attention?

>

> Thanks,

>

> Mark Patterson

> Business Transformations

Mark,

Call Application.ProcessMessages inside of your loop.

        -Steve Teixeira


Minimum Requirements - RAM

#1008.FAQ	From: jdz1@Ra.MsState.Edu (John D. Zitterkopf)

In article <3jnt3v$keb@druid.borland.com> you write:

>You would need a 386 or better with at least 6Mb of RAM. 8Mb or more

>would be recommended for best performance.

        I'd like to point out that even 8MB is a little too small to run

Delphi. It runs, you just end up SWAPING your "Delphi" Helps to disk when you

do serious work. If I had the Ca$h, I'd get at least 16MB.

John

--

 ____________   _------_  |      EE majors Do it 'til it Hz 8-)

  --------\\ ] ~-______-~ |~~~~~~~~~~~~~John D. Zitterkopf~~~~~~~~~~~~~~~

     (~~~~~\\|_(__ ~~     |    jdz1@ra.MsState.edu  jdz1@MsState.bitnet

      \______| (          | AOL: PCCJohnZ@aol.com   jdz1@isis.MsState.edu

From: dave.bell@fonix.org (DAVE BELL)

 -=> Quoting John D  Zitterkopf to All <=-

 JDZ> In article <3jnt3v$keb@druid.borland.com> you write:

 >You would need a 386 or better with at least 6Mb of RAM. 8Mb or more

 >would be recommended for best performance.

 JDZ> I'd like to point out that even 8MB is a little too small to

 JDZ> run Delphi. It runs, you just end up SWAPING your "Delphi" Helps to

 JDZ> disk when you do serious work. If I had the Ca$h, I'd get at least

 JDZ> 16MB.

Remember that Windows tends to use more and more of your systems RAM as

time goes on.  Not directly through bad programming, but there may be a

few superfluous drivers on the system, more fonts than you really need,

and all that colourful wallpaper.

It isn't hard to set up alternative versions of Windows using .BAT

files, that exchange .INI files and program groups with a stripped-down

set.  On my system, for instance, I could cut out the scanner and

multi-media drivers, quite a few fonts, and the fax-modem driver.  Also,

if it saves memory-paging, use a smaller disk-cache under Windows.  All

this has another benefit -- if (when?) you do crash the system with a

new program it'll boot faster.

Dave

... CAUTION!!! Do NOT look at laser with remaining eye.

___ Blue Wave/QWK v2.11


Delphi's EXE's are HUGE!!

#1009.FAQ	From: mikein609@aol.com (MikeIn609)

I just recently got delphi95 and i made a few VERY_SIMPLE apps, it seems

that delphi95 throws in large code for every little control you use, so

instead of having a 2-3,000 byte file as an exe ( it should have been less

then that) it came out to 250,000 every sample that it comes with

compile's the same huge way i have yet to see one go under 200,000 bytes.

Its not really greatly compiled like Turbo Pascal was, when i zip one of

them up i get a 60% compression ratio (which makes me feel like i'm

getting less bang for the byte)  Its much better to have a DLL which a

person has on their system for all delphi  programs then each exe taking

up LARGE amounts of space to perform something very simple.  I made one

app in VB and made the same app in delphi the vb app was like 6,000 bytes

compiled and the delphi app was 284,000.  The delphi app ran slightly

faster, but i would gladly sacrifice a little tiny bit of speed for a 95%

less download time, especially when dealing with a simple app which isn't

going to need all your computers resources.  Anyone got a solution to the

200,000 byte EXE problem?

From: selliott@crl.com (Steve Elliott)

MikeIn609 (mikein609@aol.com) wrote:

: Anyone got a solution to the

: 200,000 byte EXE problem?

At a demo last year, someone asked the presenter exactly that. He removed some

entries in the Uses section which were unneeded - I think that's what he did -

and got the default application down to 6K. I don't know exactly what he did,

but I'm going to try to figure it out myself. It's not a big deal for me

'cause

the apps I've been writing have a lot of functionality and therefore, a 500K

app seems reasonable - this for a large DB app. But if all you're doing is

a text entry of file browser, should be much smaller.

--

    Steve Elliott (selliott@crl.com)

From: karna@pobox.upenn.edu (Animesh Karna)

Steve Elliott (selliott@crl.com) wrote:

: MikeIn609 (mikein609@aol.com) wrote:

: : Anyone got a solution to the

: : 200,000 byte EXE problem?

: At a demo last year, someone asked the presenter exactly that. He removed

some

: entries in the Uses section which were unneeded - I think that's what he did

-

: and got the default application down to 6K. I don't know exactly what he

did,

: but I'm going to try to figure it out myself. It's not a big deal for me

'cause

: the apps I've been writing have a lot of functionality and therefore, a 500K

: app seems reasonable - this for a large DB app. But if all you're doing is

: a text entry of file browser, should be much smaller.

: --

:     Steve Elliott (selliott@crl.com)

I thought that, since version 5.0 of TP, TP had a "link optimizer": it

would strip out individual fcns from your final pgms if they weren't

being used (instead of just linking in the whole unit).  Did they stop

doing this?

From: DBRK81A@prodigy.com (Pete Royston)

karna@pobox.upenn.edu (Animesh Karna) wrote:

>

>

>I thought that, since version 5.0 of TP, TP had a "link optimizer": it

>would strip out individual fcns from your final pgms if they weren't

>being used (instead of just linking in the whole unit).  Did they stop

>doing this?

>

  Apparently they aren't doing this.  There is an "optimize size"

checkbox under PROJECT -> LINKER. which does make the code smaller.  (One

"small" app went from 270k down to 210k, still not great.)

  They definately don't smart link in this version, which I think is a

SHAME.  They should at least have an option to do it.

  I had a .dll which was 71k under BP.  In converting it, I just copied

the "uses" statement from another Delphi dll and the thing compiled to

210k.  I took off the unneeded units from the uses statement and it

finally compiled to 73k.  BP would have just left out the uncalled units.

  I consider this to me a major oversight in Delphi.

  My only other two nit picks are not allowing TABS in a listbox (had to

write my own [well, Brad Stower's]).  And not letting you put an ICON on

a button (don't want to use a bitmap in this case, want to use an icon).

  Other than that, I LOVE Delphi.

--Pete Royston - dbrk81a@prodigy.com

From: asmfiend@aol.com (AsmFiend)

"Smart Linking" only applies to static objects, that is, it doesn't work

for any virtual method you or your app may have defined but never

constructed.

For example, in BP 7 if you include the Apps unit of Turbo Vision, you get

the WHOLE turbo vision interface even if all you need is the background,

status bar, menu, and simple pop-up dialog box.  Most of TV consists of

virtual method and they don't get smart linked out.

There's no reason for Delph to be any different.  If the ads are correct,

then Delphi uses even more objects than BPW.  I'd bet money that almost

all the objects used have virtual method instead of static ones.

I find it difficult to believe that Borland would take out the "smart

linking" feature, granted that some of their staff is brain dead, but the

company as a whole wants to generate faster, smaller code (in that order).

 The BP7 manuals clearly state what is and what isn't removed by smart

linking and if you look closely in the Delphi manuals, you'll probably

find them in there yet.

From: dmurdoch@mast.queensu.ca (Duncan Murdoch)

In article <3jt18u$15k8@usenetw1.news.prodigy.com> DBRK81A@prodigy.com (Pete

Royston) writes:

>.  In converting it, I just copied

>the "uses" statement from another Delphi dll and the thing compiled to

>210k.  I took off the unneeded units from the uses statement and it

>finally compiled to 73k.  BP would have just left out the uncalled units.

I think you misunderstand how BP and Delphi compile units.  If you mention

them in the Uses clause, then you *always* include the initialization code.

Presumably Delphi units have initialization code that makes references to

large gobs of the units.

To find out whether or not the smart linker is working, don't just add and

remove units from the Uses clause.  Write a little procedure in your program

or main unit, and then don't call it.  Check the .MAP file or do a string

search in the .EXE to see if it was linked in.

Duncan Murdoch

From: dmurdoch@mast.queensu.ca (Duncan Murdoch)

In article <3jto95$dm4@newsbf02.news.aol.com> asmfiend@aol.com (AsmFiend)

writes:

>"Smart Linking" only applies to static objects, that is, it doesn't work

>for any virtual method you or your app may have defined but never

>constructed.

This is incorrect.  In BP 7 smart linking applies to all code and data.

>For example, in BP 7 if you include the Apps unit of Turbo Vision, you get

>the WHOLE turbo vision interface even if all you need is the background,

>status bar, menu, and simple pop-up dialog box.  Most of TV consists of

>virtual method and they don't get smart linked out.

The program

  uses app;

  begin

  end.

compiles to a 3728 bytes .EXE file.  It's only that large because the

App unit uses the Memory unit, and the Memory unit executes some code

in its initialization section.

Generally there is only one rule in BP 7 for whether or not code and data get

linked in:  if your program references it somehow it's in, if not, it isn't.

Of course, the rules for what constitutes a reference are a bit more

complicated.  The rule for virtual methods is that a call to them *does not*

constitute a reference, unless you use the type name (or "inherited") to force

it to act like a static call.  Virtual methods are usually linked in

indirectly, because they're referenced by the virtual method table.  The VMT

is referenced by a TypeOf call or a constructor call.

So, if you construct an instance of a type, you link in all of its virtual

methods.  If you register a type for writing it to a stream, likewise.  If you

never use any instances of the type, you don't get its code.

Duncan Murdoch

From: amcfarl@ndlc.occ.uky.edu (Andy McFarland)

AsmFiend (asmfiend@aol.com) wrote:

: "Smart Linking" only applies to static objects, that is, it doesn't work

: for any virtual method you or your app may have defined but never

: constructed.

...

: I find it difficult to believe that Borland would take out the "smart

: linking" feature, granted that some of their staff is brain dead, but the

: company as a whole wants to generate faster, smaller code (in that order).

:  The BP7 manuals clearly state what is and what isn't removed by smart

: linking and if you look closely in the Delphi manuals, you'll probably

: find them in there yet.

I wrote an algorithm for Turbo Pascal 6.0 that would smart link

unreferenced virtual methods, based on my knowledge of the TP6 TPU format.

I estimated it would add at most 30% to the compile and link time.  I do

not know if my algotithm or estimate was sound.  I would like to know what

compile and link time penalty would be acceptable if unreferenced virtual

methods were smart linked.  TP6 and BP7 virtual methods are smart linked

only if the entire object is not referenced.

Andy

From: jazzbeau@netcom.com (Steve Barnette)

It's called object-oriented, single inhertiance bloat. If you use what

appears to be a innocent little control, it has to pull the entire

hierarchy in. In the long run it doesn't matter, how long would it take

you to hand code a simalar program? Plus I think the 200k+ size is going

to be the basic size, since that probably uses most common componets.

Once you have the basic hierarchies included things aren't going to go as

fast.

The trend these days is who care how big programs are, in the long run

hardware is cheaper than developer time. That why RAD systems like

Delphi, VB, and PB are gaining popularity. Size only matters anymore if your

writing system software, then you would want to use C and assembler anyway.

As long as a program has snappy response companies don't care how much

memory or hard drive space is required. Its sad, but true.

Steve B.

Animesh Karna (karna@pobox.upenn.edu) wrote:

: Steve Elliott (selliott@crl.com) wrote:

: : MikeIn609 (mikein609@aol.com) wrote:

: : : Anyone got a solution to the

: : : 200,000 byte EXE problem?

: : At a demo last year, someone asked the presenter exactly that. He removed

some

: : entries in the Uses section which were unneeded - I think that's what he

did -

: : and got the default application down to 6K. I don't know exactly what he

did,

: : but I'm going to try to figure it out myself. It's not a big deal for me

'cause

: : the apps I've been writing have a lot of functionality and therefore, a

500K

: : app seems reasonable - this for a large DB app. But if all you're doing is

: : a text entry of file browser, should be much smaller.

: : --

: :     Steve Elliott (selliott@crl.com)

: I thought that, since version 5.0 of TP, TP had a "link optimizer": it

: would strip out individual fcns from your final pgms if they weren't

: being used (instead of just linking in the whole unit).  Did they stop

: doing this?

--

______________________________________________________________________________

_

FCS Systems Inc.

jazzbeau@netcom.com

   A nod is as good as a wink to a blind horse.


64K data segment limit in Delphi?

#1010.FAQ	From: dmurdoch@mast.queensu.ca (Duncan Murdoch)

In article <3k00a9$1r5c@pegasus.unm.edu> jreynd@unm.edu (john t UNM.HOSPITAL

reynold) writes:

>

>In article <dmurdoch.1617.2F61A7B4@mast.queensu.ca>,

>[snip]

>>No, Delphi runs under Windows in protected mode.  It has access to all of

the

>>extended and virtual memory in your computer as part of the global heap; the

>>only thing to worry about is that you can run out of selectors before you

run

>>out of memory, if you make too many small allocations.

>Hold on, Duncan.  You're telling me things I don't want to hear...I was

>using VC++ and their allocation libraries took care of selectors for

>you... doesn't Borland do the same thing with their compilers? If they

>don't, I wish they would.

The library does take care of selectors, of course.  You have control

over the strategy it uses.  If you tell it to do every allocation with a

separate selector, it'll do it.  Normally it does "suballocation", where small

allocations all come from the same segment, and just use one selector.

If you make every allocation just a bit over half of the block size it uses,

then every one will get a separate selector, and you can quickly run out of

selectors.  I think there's a system-wide limit of 8192, or some small number

like that.

Duncan Murdoch

From: Raymond@mcgltd.demon.co.uk (Raymond Wilson)

In article <3jp7al$pkk@epsilon.qmw.ac.uk>

           P.K.Guinnessy@qmw.ac.uk "ugfa114" writes:

> In article <3jng52$e1v@ornews.intel.com>

> Michael Brodesky <mbrodesky@sc9.intel.com> writes:

> > Is there any way to get around the 64K data segment limit in Delphi

>

> Probably the same way as you do in TP7, you use pointers to the heap.

> However this does not allow access to extended or expanded mode so you

> will probably be limited to roughly 200-300K (depending on the size of

> your program.

I don't believe this is correct. My impression is that Delphi produces 16-bit

protected mode windows executables. This allows you access to all the memory

of the machine (ie: the available pool that is) just like plain old DOS

protected mode does. Therefore your available heap is pretty much limited

only by the available memory and/or disk on the machine.

Raymond.

--

Raymond Wilson,      Software Engineer.      Morgan Collis Group Ltd,

                                             The Mill, Millbrook Close,

Yes, they ARE fond of mills here!            St. James Mill Rd,

Ph: +44 604 580-980  Fax: +44 604 589-208    Northampton NN5 5JF, Britain.

From: jreynd@unm.edu (john t UNM.HOSPITAL reynold)

[snip]

>No, not at all.  The Delphi heap code does sub-allocation of Windows

>heap blocks, just like TPW/BP7 did.  That is, "big" allocations go

>directly into their own Windows heap block; "small" allocations cause

>the heap manager to request one biggish block which it then breaks into

>pieces for subsequent small allocations.  That is, you have access to

>all the physical and virtual RAM in your user's Windows machine ...

>whatever shows in the Program Manager's Help About dialog.  The plus

>side of suballocation is it stretches the hardware limit of 8192

>selectors; the minus side is that you don't get a GPF when you go

>past the end of your small block.

Now there's the answer I was looking for...I knew MS provided that, and

since Borland is reputed to making better compilers, I knew they had to,

as well.

Thanks

John Reynolds

P.S.  I wasn't the original poster...I just saw an answer I didn't like

but didn't have the knowledge to rebuff.


API calls?

#1011.FAQ	From: bstowers@cybernetics.net (Brad Stowers)

walsha@iccgcc.cle.ab.com wrote:

> I'm trying to do something like:

>    myHWnd := GetDesktopWindow;

>    myHwnd.GetWindowExtent();

> in order to size a form to the width of the Desktop Window.

Check out the Screen variable available in the Forms unit.  It is based on

TScreen (keyword TScreen in DELPHI.HLP).  You want something like:

...

  MyForm.Width := Screen.Width;

  MyForm.Height := Screen.Heigth;

...

btw, why don't you just make the form maximized at startup?

> Once I get myHWnd data, should I resize all the form's components,

> like any TextBoxes?

Yes.

Regards,

Brad

--------------------------------------------------------

Brad Stowers             |  bstowers@cybernetics.net

deltaComm Development    |  My views are my own...

Telix for Windows & DOS  |  Keep yer hands off of 'em.

--------------------------------------------------------

      http://www.cybernetics.net/users/bstowers/


TBlobField and the meaning of life...

#1012.FAQ	From: The Green Meddler <kilgalen@tde.com>

BRC@roadnet.ups.com (Buff Colchagoff) wrote:

>

> *************************************************

> Anybody work a lot with the TBlobField in Delphi?

> *************************************************

>

> I'm trying to write some code that can store data

> in a TBlobField, but compress it before it stores the

> data, and uncompress when it retrieves the data.

>

> I tried to just open a table, and create a

> TBlobStream on a TBlobField in the table.

>

> I get a GPF when I try to create the TBlobStream.

>

how are you creating the TBlobStream? i had some GPF until

i did it this way:

MyBlobField := TBlobStream.Create( self ).

ie create returns a pointer but you call it from the generic class

rather than the instance variable.

> The TBlobField is valid at that point.  Anybody

> know why this might occur?

> Does this seam like the logical way to accomplish

> my goal? i.e. <data> ->[compressor]-> TBlobStream -> TBlobField

>

> Any help is greatly appreciated!

> Thanks.

>

> ******ps:  Anybody know of any TGraphic subclasses that

> can access other picture formats than BMP and WMF?????

the only other one it supports is icon (.ICO) files. and it's

a PAIN that it doesn't support resources. subclassing, anyone...?

>

>

> Buff Colchagoff            Roadnet Technologies, Inc.

> brc@roadnet.ups.com        A United Parcel Service Company

> The opinions expressed are my own and do not necessarily

> represent those of Roadnet Technologies or

> United Parcel Service.

GM


Using TrueGridPro

#1013.FAQ	From: EHCARTER@ADM1.BYU.EDU (Eric Carter)

In article <3ji0up$9vd@tdelx01.tde.com>, The Green Meddler

<kilgalen@tde.com> wrote:

> Geoffrey Anderson <70534.3336@CompuServe.COM> wrote:

> >

> > Can anyone try using Apex TrueGrid Pro with Delphi? I will buy Delphi only

> > (Anyone want to start a "compatibility list" of VBXs that work with (ie,

Well to start you can *not* include TrueGrid Pro on your list.  It is not

a version 1.0 VBX.

--

Eric Carter        | Eric_Carter@byu.edu

PACTS Development  | erichc@yvax2.byu.edu


One form calls another

#1014.FAQ	From: koterski@genghis (Steve Koterski)

Steve Wiser (steve.wiser@richcon.com) wrote:

[...]

: Another thing how does one go about calling one form from another

: form.  Its a snap in CA-Realizer but what do you do it Delphi. In the

: same project, I make two forms and place a button on each form.  Set up

: an event for each button to call the other form, such as;

: Begin;

: Form1.Visible:=False;

: Form2.Visible:=True;

: end;

: but it does not like this, it says form2 isn't delcared or something

: when I do a syntax check.  I go into each form's uses section add the

: others unit's (form*) name and then it says I have a circular reference

: somewhere?????

First, include the unit containing the second form in the Uses section

that contains the calling form. Then simply call the Show method of the

second (called) form.

   procedure TForm1.Button1Click(Sender: TObject);

   begin

      Form2.Show;

   end;

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

From: The Green Meddler <kilgalen@tde.com>

steve.wiser@richcon.com (Steve Wiser) wrote:

>

> Hello;

>

> I am just starting to try to understand Pascal and Delphi in

> particular.  The specific situation that I am interested in right now

> is how to get the circular reference example in the help system to

> work.

>

> Does anyone know how to get Delphi to accept a non-form program such

> as my example above.  I try to open a new unit and copy this code into

> it.  Then I do a syntax check on it and I can't get it past all the

> errors.  Its says something about not having a proper Tclass declared

> or something or other..

>

> Another thing how does one go about calling one form from another

> form.  Its a snap in CA-Realizer but what do you do it Delphi. In the

> same project, I make two forms and place a button on each form.  Set up

> an event for each button to call the other form, such as;

>

> Begin;

> Form1.Visible:=False;

> Form2.Visible:=True;

> end;

>

> but it does not like this, it says form2 isn't delcared or something

> when I do a syntax check.  I go into each form's uses section add the

> others unit's (form*) name and then it says I have a circular reference

> somewhere?????

>

> Whats going on with Delphi?

>

> Any help for a complete novice is appreciated.

>

> Thanks

> Steve

>

> ---

>  * KWQ/2 1.2g * Bablyon Five, the best of Televison...

you need to put the second unit in the uses section of the

IMPLEMENTATION area ofthe second unit. that'll deal with the

CUR problem. if you have further difficulties, email me.

gotta help out a fellow babelmaniac....(g)

GM


193k file??? HELP!

#1015.FAQ	From: Steve Teixeira <steixeir@borland.com>

lpegasus@netcom.com (Zack Smith) wrote:

>

> egads... i just got delphi today... I love it.... if they had done this

> for tvision i probably would have used it:)... but.... i have a proggy

> that puts up a label and a button  and thats it... oh and has an

> integrated ico file... yet the thing is 190k.... so i took out all the

> units i could.... still 130k... anyone have any ideas on how to fix this???

>

You can shrink your app even more by not including debug info and by

clicking the "Optimize for Size and Load Time" box.  FWIW, there is a

certain amount of initial overhead involved in using VCL, but as the number

of component in your app increases, the size of your app increases only

modestly.

        -Steve Teixeira

         steixeir@borland.com


Accessing MS-DOS Environment Variables from Delphi?

#1016.FAQ	From: Steve Teixeira <steixeir@borland.com>

mac@zeus.hsrc.ac.za (Malcolm Coulter) wrote:

>

> In article <3jq1sq$i9@tdelx01.tde.com> The Green Meddler <kilgalen@tde.com>

writes:

>

> >jpmccreesh@pines.demon.co.uk ("John P.McCreesh") wrote:

> >>

> >> Another newbie question I'm afraid.

> >>

> >> How do I manipulate MS-DOS environment variables (i.e. variables created

> >> by the MS-DOS 'SET' command) from within Delphi?  I've searched the

on-line

> >> help without success...

> >>

>

> >a good question! i just tried envcount and envstr and the

> >delphi compiler never heerd of em. try adding the dos unit

> >to a delphi project and see what happens...

> ---------------------------------------------------------------------

> ....may be something to do with Delphi being written for Windows95 where,

for

> Windows programs, there just may be *no* DOS environment. There appear to be

> differences of opinion (or is it terminology?) as to whether

> (a) Windows95 runs under MS-DOS 7 or if

> (b) MS-DOS 7 runs under Windows95 or

> (c) both (a) and (b) are true (in some sense).

>

Just use the GetDOSEnvironment() API function.  It returns a null-separated

list of environment variables and values.  The list is terminated by a double

null.

        -Steve Teixeira

         steixeir@borland.com

From: The Green Meddler <kilgalen@tde.com>

mac@zeus.hsrc.ac.za (Malcolm Coulter) wrote:

>

> In article <3jq1sq$i9@tdelx01.tde.com> The Green Meddler <kilgalen@tde.com>

writes:

>

> >jpmccreesh@pines.demon.co.uk ("John P.McCreesh") wrote:

> >>

> >> Another newbie question I'm afraid.

> >>

> >> How do I manipulate MS-DOS environment variables (i.e. variables created

> >> by the MS-DOS 'SET' command) from within Delphi?  I've searched the

on-line

> >> help without success...

> >>

>

> >a good question! i just tried envcount and envstr and the

> >delphi compiler never heerd of em. try adding the dos unit

> >to a delphi project and see what happens...

> ---------------------------------------------------------------------

> ....may be something to do with Delphi being written for Windows95 where,

for

> Windows programs, there just may be *no* DOS environment. There appear to be

> differences of opinion (or is it terminology?) as to whether

> (a) Windows95 runs under MS-DOS 7 or if

> (b) MS-DOS 7 runs under Windows95 or

> (c) both (a) and (b) are true (in some sense).

>

>

>

no, you use GETDOSENVIRONMENT to read the environment. haven't

found out how to set them, tho...

GM

From: jpmccreesh@pines.demon.co.uk ("John P.McCreesh")

In article <3k4q0c$hs1@druid.borland.com>

           steixeir@borland.com "Steve Teixeira" writes:

> Just use the GetDOSEnvironment() API function.

Thanks Steve!  For info, here is a code fragment that works for me - attach

this to the onClick of a new blank form, run it, and click it...

procedure TForm1.Button1Click(Sender: TObject);

var

 p : pointer;

 x : string;

 begin

 p := GetDOSEnvironment;

 WHILE StrLen(p) > 0 do begin

   x := StrPas(p);

   MessageDlg(x, mtInformation, [mbOk], 0);

   p := StrEnd(p) + 1;

 end;

 close;

end;

+---------------------+------------------------------------------------------+

 John P.McCreesh      |  Internet: jpmccreesh@pines.demon.co.uk

 Forbo-Lancaster Ltd. |  X.400:    c=GB,a=CWMAIL,p=FORBO,g=John,s=McCreesh

 Lancaster, England   |  Voice:    +44 (0) 1524 65222  Fax: +44 (0) 524 61638

From: pcsd1055@altair.selu.edu

Try looking in Delphi help under 'Kernal Functions'.  There you will

find a windows API function called 'GetDOSEnvironment' that will give

you a far pointer to the DOS environment variables...you will have to

write a little routine that retrieves the desired environmet var.  If

you need the code...let me know and I will e-mail it to you.

----------------------------------------------------------------------

Bill Plunkett

5th Circuit Court of Appeals

New Orleans, La.

----------------------------------------------------------------------

IF A KLUDGE WORKS...DON'T FIX IT.

----------------------------------------------------------------------


How to share variables between 2 units in delphi. Help.

#1017.FAQ	From: bstowers@cybernetics.net (Brad Stowers)

imranh@ece.rutgers.edu (Imran Hussain) wrote:

>       I am new to pascal but have been programming in C for long. The

> question is how do I share variables and functions that can be visible to

> all the units in pascal. To be more precise, is there such a thing as

> a header file like in C.

The interface section of a unit is what you are looking for.  Take the

following unit for example:

---------------

unit MyStuff;

interface

type

  TFooBar = record

    W, H: integer);

  function Foo(x: TFooBar): boolean;

var

  GlobalFooBar: TFooBar;

implementation

var

  PrivateFooBar: TFooBar;

function Foo(x: TFooBar): boolean;

begin

  Result := x.W = y.H;

end;

procedure Bar(y: integer);

begin

  { do something with y);

end;

initialization

  GlobalFooBar.W := 10;

  GlobalFooBar.H := 100;

  PrivateFooBar.W := 20;

  PrivateFooBar.H := 200;

end.

---------------------------

Using the above example, the function Foo and the variable GlobalFooBar

would be available to all who use (via the USES clause) the MyStuff unit.

Because the procedure Bar and the variable PrivateFooBar are not declared

until the implementation section, they are only available inside the

MyStuff unit.

>       Second question: Is there any library function that would convert

> a string into PChar and vice versa.

StrPCopy and StrPas, respectively.

Regards,

Brad

--------------------------------------------------------

Brad Stowers             |  bstowers@cybernetics.net

deltaComm Development    |  My views are my own...

Telix for Windows & DOS  |  Keep yer hands off of 'em.

--------------------------------------------------------

      http://www.cybernetics.net/users/bstowers/

From: Marc@landscap.demon.co.uk (Marc Palmer)

In article: <3k44ts$6f6@ece.rutgers.edu>  imranh@ece.rutgers.edu (Imran

Hussain) writes:

>

> Hello!,

>       I am new to pascal but have been programming in C for long. The

> question is how do I share variables and functions that can be visible to

> all the units in pascal. To be more precise, is there such a thing as

> a header file like in C.

>

>       Second question: Is there any library function that would convert

> a string into PChar and vice versa.

>

At a guess I'd say put a 'var' section in the interface part of your unit.

********************************************************************

* Marc P.                               E-Mail me for PGP 2.6 key  *

********************************************************************


Desktop Version vs. Client Server

#1018.FAQ	From: koterski@genghis (Steve Koterski)

Wim Neimeijer (wneimeij@vmprofs.estec.esa.nl) wrote:

: I contacted Borland in the Netherlands and asked them if

: the database controls and database access objects (VCL) are included

: in the Delphi Desktop version.

: They said it is included but someone said it is only available with

: the Delphi Client/Server version.

: Is there anybody who has Delphi Desktop and can check this for me ?

The Visual Components Library (VCL) is available in both the Desktop

and the Enterprise (client-server) versions. What is not available in

the Desktop version is the *source code* for the VCL. It is available as

an optional add-on, though.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


Using DOSERROR

#1019.FAQ	From: DBRK81A@prodigy.com (Pete Royston)

ddm7047@ucs.usl.edu (McCrory Dave D) wrote:

>

>

>  Well I can't figure out what is the equivalent for DosError in Delphi?

 I have a routine that uses DosError = 0, how can I get Delphi to perform

the same function?\

  I am not sure which function you are trying to use, but I ran into this

with FINDFIRST and FINDNEXT (the directory commands).  In BP7 you called

t hem, then checked DOSERROR.  In Delphi, FINDFIRST and FINDNEXT return a

value (they are functions, not procedures) which has the value you can

use like DOSERROR.  In fact, I just took my same procedure, declared

DOSERROR as a local variable and then changed

  FINDFIRST('*.*',fa_archive)    { or whatever the exact text is }

      to

  DOSERROR := FindFirst('*.*',fa_archive)

    While DOSERROR = 0 do

      begin

           ...

          DOSERROR := FindNext;

      end;

d>  I am >+---------------------------------------------------------------

---------------+|

               ||     Dave McCrory - University of

Southwestern Louisiana, Lafayette , USA     ||     E-Mail ddm7047@ucs.usl.

edu +---------------------------------------+     ||     CyberSurfing is

best when it's hot and wet! +----------------------+     ||

                                                               |+---------

---------------------------------------------------------------------+


Compiling DLLs

#1020.FAQ	From: raffelm@netcom.com (Matt Raffel)

keeper@netcom.com (Zoo Keeper) writes:

> Delphi can be used to compile DLLs.  A VBX is simply a renamed DLL

> with certain standard callbacks for the VBX interface.  Thus, Delphi

> should be able to create DLLs.

>

> The question is, how do you link in VBAPI.LIB, and what about all of

> the header definitions in VBAPI.H?  Must you recreate all this by

> hand, or is there a way to do it?  Those of you who have written

> VBX's in Pascal, roughly how's it done?

>

> --

VBAPI.H is written in C--so you would have to make your own translations

into pascal.

How to link in the VBAPI.LIB--that's a good question and I would like

to know the answer

--

--

raffelm@netcom.com

============================================================

"An economy hampered by restrictive tax rates will never produce enough

revenue to balance our budget, just as it will never produce enough jobs

or enough profits"

                                       - John F. Kennedy

From: Steve Teixeira <steixeir@borland.com>

Subject: Re: A Delphi gap?

Date: 14 Mar 1995 19:21:15 GMT

raffelm@netcom.com (Matt Raffel) wrote:

>

> keeper@netcom.com (Zoo Keeper) writes:

> > Delphi can be used to compile DLLs.  A VBX is simply a renamed DLL

> > with certain standard callbacks for the VBX interface.  Thus, Delphi

> > should be able to create DLLs.

> >

> > The question is, how do you link in VBAPI.LIB, and what about all of

> > the header definitions in VBAPI.H?  Must you recreate all this by

> > hand, or is there a way to do it?  Those of you who have written

> > VBX's in Pascal, roughly how's it done?

> >

> > --

>

> VBAPI.H is written in C--so you would have to make your own translations

> into pascal.

>

> How to link in the VBAPI.LIB--that's a good question and I would like

> to know the answer

> --

You don't need to link in a .LIB file to talk to a .DLL.  You just need to

translate the .H file into an interface unit that contains EXTERNAL references

to the DLL.

        -Steve Teixeira

         steixeir@borland.com

From: victorddm@delphi.com

Subject: Re: A Delphi gap?

Date: Fri, 17 Mar 95 19:49:34 -0500

Zoo Keeper <keeper@netcom.com> writes:

>The question is, how do you link in VBAPI.LIB, and what about all of

>the header definitions in VBAPI.H?  Must you recreate all this by

>hand, or is there a way to do it?  Those of you who have written

Somebody did recreate them as a Pascal Unit. You could get it in Compuserve

GO DELPHI and search for VBX. I believe it must be too in ftp.Borland.com.

--Victor J. DuLuc


Reading and displaying a line from a file

#1021.FAQ	From: Steve Teixeira <steixeir@borland.com>

ddm7047@ucs.usl.edu (McCrory Dave D) wrote:

>

>       Okay, I have had Delphi for about 3 days now, and I still cannot

figure out how to do this simple task.

>

>       Open a file, then read a line from it, then display that line if it

> contains a string (using Pos).

>

> Please if anyone can help "get me on track" I would appreciate it.

>

>

> --

>

+-----------------------------------------------------------------------------

-+|

||     Dave McCrory - University of Southwestern Louisiana, Lafayette , USA

 ||     E-Mail ddm7047@ucs.usl.edu +---------------------------------------+

  ||     CyberSurfing is best when it's hot and wet! +----------------------+

   ||

|+----------------------------------------------------------------------------

--+

Put a button and an edit control on an empty form.  Double click on the

button,

and use this code:

procedure TForm1.Button1OnClick(Sender: TObject);

var

  F: TextFile;

  S: String;

begin

  AssignFile(F, 'MYFILE.TXT');

  Reset(F);

  while not EOF(F) do begin

    Readln(F, S);

    if Pos('Some Substring', S) > 0 then

      Edit1.Text := S;

  end;

  CloseFile(F);

end;

Hope that helps,

        -Steve Teixeira

         steixeir@borland.com

Subject: Re: Novice Delphi Question

From: The Green Meddler <kilgalen@tde.com>

Date: 15 Mar 1995 05:05:00 GMT

ddm7047@ucs.usl.edu (McCrory Dave D) wrote:

>

>       Okay, I have had Delphi for about 3 days now, and I still cannot

figure out how to do this simple task.

>

>       Open a file, then read a line from it, then display that line if it

> contains a string (using Pos).

>

> Please if anyone can help "get me on track" I would appreciate it.

>

>

> --

>

+-----------------------------------------------------------------------------

-+|

||     Dave McCrory - University of Southwestern Louisiana, Lafayette , USA

 ||     E-Mail ddm7047@ucs.usl.edu +---------------------------------------+

  ||     CyberSurfing is best when it's hot and wet! +----------------------+

   ||

|+----------------------------------------------------------------------------

--+

your problem is that what you want to do is pascal, not delphi.

go to the testeditor example in the examples directory. it has

exactly the code you need.

GM

From: Ken Masters

Essentially, you're looking for the Delphi equivalent of Pascal's

WriteLn.  There is no equivalent.

You can do what Steve suggests, but use a Label instead of an

Edit Component.  So, the line reading:

 Edit1.Text := S

will read

 Label1.Caption := S

Simply by assigning the string, it will automatically be displayed on

the form.

Ken


DELPHI beeps at me

#1022.FAQ	From: mobergru@oslonett.no (Rune Moberg)

In article <3k821e$jum@ccnet.ccnet.com>,

gabriel@ccnet.com (Gabriel Beccar) wrote:

> I am trying to design a form with a bunch of edit controls where the

> cursor can move from one control to the next by pressing the arrow keys

> or the return key. Drawing on my experience with Turbovision, I wrote a

> method which does the trick except that the machine beeps when I press

> the return key (the focus shifts to the next control either after or

> before beeping). I cannot figure out why. I would appreciate any

> suggestions. Thank you.

>

> the code used is as follows:

>

> procedure TForm1.FormKeyDown(Sender: TObject; var key : Word;

>                              Shift: TShiftState);

I'm pretty sure that I've come accross similar behavior in BPW a year

back or so. Anyway, you may want to check if the key gets processed

further, maybe try to reset key to zero (to avoid further processing

if you intercept it). Anyway, prevent further processing, since you've

changed the focus from the old control...

  =======================================ftp to:==========================

-== R.Moberg, author of CD-Player Pro! = ftp.cica.indiana.edu            ==-

  =======================================/pub/pc/win3/sound/cdppro45.zip==

From: Gabriel Beccar-varela <gabriel@ccnet.com>

>[Delphi beeps when traping return key to shift focus]

I solved the problem. In the form's properties, I set the

"PreviewKey" to TRUE. Then, I assigned procedures to the form's

OnKeyDown and OnKeyPress. The FormKeyDown procedure does the job

of changing the focus when up arrow, down arrow and return are

pressed. The FormKeyPress simply clears the key to #0 if the

return key is pressed. I make no special settings to the edit

controls.


Turbo Pascal and Delphi

#1023.FAQ	From: Steve Teixeira <steixeir@borland.com>

jason.hatfield@tbsoftware.com (Jason Hatfield) wrote:

>

> Question(s):

> 1) Is Delphi Turbo Pascal?  IE: They both do the same thing?

No. Delphi is a new product that combines an Object Pascal compiler, Rapid

Application Development, and scalable database access.

> 2) Will Delphi always be compatible with pascal?

The current version of the Delphi compiler will compile TP/BP code.  I

don't know at this point whether future versions will.

> 3) Is borland still making Turbo Pascal? (& will they continue to)

Yep.  In fact, we believe BP7 is still one of the best DOS development

platforms out there.

> 4) Is comp.lang.pascal going to be deleted?

It appears c.l.p. is going to be reorganized.  That's in the process.

> 5) What does delphi offer that Turbo Pascal 7.x does not?

New language features like exception handling and runtime type information,

rapid application development, database access, a path to Win32, built-in

VBX support, among other things.

        -Steve Teixeira

         steixeir@borland.com


Bitwise Operations and Links to a C++ module

#1024.FAQ	From: mehrban@fc.hp.com (Jam Mehrban)

Thanks Jeroen,  I appriciate your help.

> Jeroen Pluimers (jeroenp@dragons.nest.nl) wrote:

>

> :  > 1-  How do you do bitwise and logical operations (and, or, xor)

> :  >     &, &&, |, ||, ^ operations in C?

>

> : Use the and, or, xor, etc bitwise oprators. Look in the online help for

> : 'bitwise operators'.

   I can not believe I missed "bitwise operators in the online help.

> :  > 4- Can you statically link a C++ module to Delphi?

>

> : Yes, but is difficult. Steve Teixeira (steixeira@wpo.borland.com) wrote an

> : article about this for The Pascal Magazine. He can probably send you code

> : samples.

>

> : BTW: It is much easier to dynamically link to a C++ module using DLLs.

Delphi

> : supports the CDECL calling convention, so writing an import unit is not

too

> : difficult.

   I was more thinking of the time I need to have a single .EXE file rather

   than an .EXE and a DLL file.

> : Jeroen

    Best regards,

    Mehrban


DOS and Win execs in one .exe file

#1025.FAQ	From: edm@gocart.eng.hou.compaq.com (Ed McCreary)

In article <3ka5ht$b5p@vanbc.wimsey.com> jzielin@vanbc.wimsey.com (Jacob

Zielinski) writes:

   Does anybody know how to put both DOS and Windows programs into one

executable?

   I know this can be done because every Windows program also contains a small

   DOS program that says "This program req's MS Win".

   Quaterdeck also does this in their MFT.EXE program. I'm guessing that they

   compiled two program under two different systems and then used some kind

   of a utility to join them.

   Is this just as simple as creating both a regular exe header and extended

one

   then binary copying both exe (except for their headers) into the new file

and

   modifying code entry points, relocations/etc... in the new headers?

   I doubt there is anything out there that does this sort of thing, but if

   anybody can provide some hints it would be appreciated.

The dos program that is bound to your windows program is determined by

the STUB entry in the .DEF file.  Winstub.exe is usually used which

outputs the familiar "This program requires Microsoft Windows.".

--

   .__o   Ed McCreary            "The Information Superhighway, sanitized

 _-\ <,-  Compaq Computers        for your protection."

(*)/ (*)  edm@twisto.compaq.com

From: timtroyr@ionet.net (Tim Robinson)

In article <3ka5ht$b5p@vanbc.wimsey.com>,

   jzielin@vanbc.wimsey.com (Jacob Zielinski) wrote:

>Does anybody know how to put both DOS and Windows programs into one

executable?

>

Put the following in your DEF file:

STUB 'MYDOSPGM.EXE'

| Tim Robinson                   | Those who would give up essential |

| The Original Camelot BBS:      | liberty  to   purchase  a  little |

| 918-749-5792, 5793 (Excalibur) | temporary safety, deserve neither |

| http://www.ionet.net/~timtroyr | liberty nor safety.  Ben Franklin |


Control arrays in Delphi?

#1026.FAQ	From: The Green Meddler <kilgalen@tde.com>

graham@penny.mhn.org (Graham Mainwaring) wrote:

>

> I've run into this a couple times, but have assumed it was just something

> I missed and worked around it. Does Delphi not support anything similar

> to control arrays in Visual Basic?

>

> The situation: As a learning project, I'm trying to write "go-moku" in

> Delphi. I want to display a grid of ten by ten dots, each of which can be

> red, black or invisible. To me, it seems obvious that what I need is a

> ten by ten array of TShape objects. But if I try to create such a thing,

> I wind up with Shape1, Shape2, ..., Shape100 instead of, say, Shape[0..99].

>

> Does anyone who's further along the Delphi learning curve have any

> suggestions or comments about this?  Am I looking at this in a non-Delphi

> sort of way? Is there something really obvious that I've missed out on?

>

> -Graham

use the components array property of the main form, or whatever

sub-form/control you're using. see the OLE demos for excellent

example code.

I have GOT to get the FAQ out...

GM

From: sraike@iconz.co.nz (William M. Raike)

In article <joea.6.0072A30E@mindspring.com>, joea@mindspring.com (Joe

Antonecchia) says:

>

>Is there way to implement control arrays in Delphi?  The controls do not have

>an index property!

There is!  Somewhere, such as in the private section of the main form

class declaration, declare something like the following:

 private

    { Private declarations }

    buttons : array[0..255] of TButton;

  public

    { Public declarations }

  end;

const

  lastleft : Integer = 10;

  ctlcount : Integer = 0;

 Then, suppose you have a TButton called btnCreateButton.

Just as an example, in its OnClick event you could create a

new button by executing code like the following:

procedure TfrmDynCtrl.cmdCreateClick(Sender: TObject);

begin

    buttons[ctlcount] := TButton.Create(self);

    buttons[ctlcount].parent := self;

    buttons[ctlcount].top := 80;

    buttons[ctlcount].left := lastleft;

    buttons[ctlcount].width := 64;

    buttons[ctlcount].height := 32;

    buttons[ctlcount].caption := 'Button' + IntToStr(ctlcount);

    buttons[ctlcount].OnClick := self.ButtonClick;

    Inc(lastleft, 80);

    Inc(ctlcount);

end;

You can use the Tag property to identify a member of the buttons[] array.

From: jwales@silver.ucs.indiana.edu (Jimmy -Jimbo- Wales)

Chaim Drellich  <73040.3300@CompuServe.COM> wrote:

>We work in a similar environment. You can not create a vb type

>control array. However, you can create an object of the control,

>including code, and then place as many of them on the form

>as you need.

I'm not sure that I understand how to do this.  Let me explain my

problem by telling you all what I'm doing, step-by-step, and then

asking a question.

First, create a new project with a blank form and add a label to it.

Second, add the following code to the interface section of Unit1:

var

   MyLabel: TLabel;

Third, write the FormCreate procedure as follows:

procedure TForm1.FormCreate(Sender: TObject);

begin|

   MyLabel := TLabel.Create(Form1);

          {Should create instance of MyLabel with Form1 as owner.}

   MyLabel.Top := 100;

   MyLabel.Left := 50;

   MyLabel.Caption := 'My label!';

   MyLabel.Show;

end;

Finally, run the code.

Notice that the code compiles just fine, but the label doesn't appear.

Where is it?  I tried also setting the height and width of the label,

on the theory that maybe it was _there_, but of zero height and width.

>P.S. To do this use the .create in Delphi.

I agree that this sounds like the right approach, but I must be missing

something.  Nevermind for now my earlier question about arrays... I guess

I'm confused about some even simpler stuff.  The basic question is this:

how can I create a new control (label, button, etc.) at runtime based on

my needs at the time?  Surely it wouldn't make sense for me to have to

draw every possible control I would ever need on the form at design time

and make them all invisible?

Thanks to anyone who can help!

--Jimbo

From: koterski@genghis (Steve Koterski)

Jimmy -Jimbo- Wales (jwales@silver.ucs.indiana.edu) wrote:

: I am learning Delphi and Pascal all at the same time.  I'm an

: experienced Visual Basic and sometimes Visual C++ programmer.

: In Visual Basic it is very easy to create a control array.

: For example, I can have several labels on a form and call them

: label(0), label(1), label(2), etc.  This is very convenient

: for many operations, for example, I can write a for...next loop

: to assign a list of values read from a file to a set of labels

: on the form.

: How can I do this in Delphi?

Look at the Components and ComponentCount properties in the help file.

Basically, the Components property is an array of all the objects in

a given parent object, and ComponentCount is a count of those array

elements. Examples are provided in the help file to demonstrate the use

of these properties.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

From: The Green Meddler <kilgalen@tde.com>

jwales@silver.ucs.indiana.edu (Jimmy -Jimbo- Wales) wrote:

>

> Chaim Drellich  <73040.3300@CompuServe.COM> wrote:

> >We work in a similar environment. You can not create a vb type

> >control array. However, you can create an object of the control,

> >including code, and then place as many of them on the form

> >as you need.

>

> I'm not sure that I understand how to do this.  Let me explain my

> problem by telling you all what I'm doing, step-by-step, and then

> asking a question.

>

> First, create a new project with a blank form and add a label to it.

>

> Second, add the following code to the interface section of Unit1:

>

> var

>    MyLabel: TLabel;

>

> Third, write the FormCreate procedure as follows:

>

> procedure TForm1.FormCreate(Sender: TObject);

> begin|

>    MyLabel := TLabel.Create(Form1);

>           {Should create instance of MyLabel with Form1 as owner.}

>    MyLabel.Top := 100;

>    MyLabel.Left := 50;

>    MyLabel.Caption := 'My label!'

add:

     MyLabel.Visible := true;

     MyLabel.Parent := self;

and i think you'll see it.

;

>    MyLabel.Show;

> end;

>

> Finally, run the code.

>

> Notice that the code compiles just fine, but the label doesn't appear.

> Where is it?  I tried also setting the height and width of the label,

> on the theory that maybe it was _there_, but of zero height and width.

>

> >P.S. To do this use the .create in Delphi.

>

> I agree that this sounds like the right approach, but I must be missing

> something.  Nevermind for now my earlier question about arrays... I guess

> I'm confused about some even simpler stuff.  The basic question is this:

> how can I create a new control (label, button, etc.) at runtime based on

> my needs at the time?  Surely it wouldn't make sense for me to have to

> draw every possible control I would ever need on the form at design time

> and make them all invisible?

>

> Thanks to anyone who can help!

>

> --Jimbo

>

>

>

GM


Async Professional for Windows

#1027.FAQ	From: unified@clark.net (Charles Bouknight)

Luiz Marques (luiz.marques@mandic.ax.apc.org) wrote:

: K>Async Professional for Windows is First

:  >Comm Toolkit to Have MFC and OWL Classes

:     Has anybody out there been using this toolkit? I'm interested,

: but I would like to hear something from satisfied users...

I'm using Async Professional for DOS, and love it.  I'll soon be

purchasing the Windoze version.

TurboPower has super techincal support, an invaluable asset when you're

just learning how to use any of their well-documented toolkits.

Good Luck.


Frequently Asked Questions - What is Delphi?
What is Delphi?

#1028.FAQ	From: koterski@genghis (Steve Koterski)

[NOTE: These postings were made before the Delphi groups were created]

Jon Weinstock (Tw@ix.netcom.com) wrote:

: HI, I read this usenet group called comp.lang.PASCAL and all I see is

: delphi crap. What is it and how is it related to pascal? It is a

: programming utility? What is it?! And why doesn't it get its own group

: already?!

Delphi is a Rapid Application Development (RAD) package that has the three

main features:

   * Visual component-based design.

   * Optimizing native code compiler.

   * Scalable database access.

A description of all its features would be too wordy and take up too

much band-width here, but you can get more information on-line at the

Delphi WWW home page. This Web page has a fairly detailed description

of Delphi, Q&As, hardware requirements, and even screen-shots (only

useful if you have a graphical Web browser, of course). The URL is:

   http://loki.borland.com:8080

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


Is delphi a repackage of TP7 for Windows?

#1029.FAQ	From: dmurdoch@mast.queensu.ca (Duncan Murdoch)

In article <3kd87r$aah@pipe2.pipeline.com> mwj@pipeline.com (Jin Mai) writes:

>Is Delphi a repackage of TP7 for windows with Report Smith and

>Data access engine throw in? What features defferenciate Delphi from

>TP7 for Windows and VB and what really make Delphi shine?

Not at all.  TP for Windows relied on OWL for Windows programming; as you said

in another message, this required a lot of Windows knowledge to use.  Delphi

provides a copy of OWL for people moving from TPW, but you would normally use

VCL, a completely different and much better interface to Windows.  For most

programs, you'll never need to see the Windows API at all.  Even if you want

to do something like hooking a windows message, you can do it at a higher

level.  Of course, there are things that VCL doesn't handle, and for those

cases, you can go to the API if you want.

Duncan Murdoch


Delphi MessageBox and variable?

#1030.FAQ	From: dionkk@ix.netcom.com (Dion Kurczek)

In <D5MBID.F04@eskimo.com> mcmillan@eskimo.com (Gary L. McMillan)

writes:

>

>I'm not having any luck using a string variable in the text

>parameter of a MessageBox Method in Delphi. I can use real text

>successfully, but not a variable. What am I missing?

>

>

I had the same headaches with Delphi's MessageBox method.  I wound up

writing my own wrapper around the standard Windows MessageBox function

(defined in the WinProcs unit).  This was a much more satisfying

solution.

function MsgBox( const sMsg, sCaption: String; nFlags: integer ):

integer;

var

  lpMsg, lpCaption: PChar;

begin

  lpMsg := StrAlloc( Length( sMsg ) + 1 );

  lpCaption := StrAlloc( Length( sCaption ) + 1 );

  StrPCopy( lpMsg, sMsg );

  StrPCopy( lpCaption, sCaption );

  MsgBox := MessageBox( 0, lpMsg, lpCaption, nFlags );

  StrDispose( lpCaption );

  StrDispose( lpMsg );

end;

From: The Green Meddler <kilgalen@tde.com>

mcmillan@eskimo.com (Gary L. McMillan) wrote:

>

> I'm not having any luck using a string variable in the text

> parameter of a MessageBox Method in Delphi. I can use real text

> successfully, but not a variable. What am I missing?

>

MessageBox is a windows API call, and needs a PChar, not a string.

To use strings, call MessageDlg. good examples in the help.

GM

From: jnhodges@nps.navy.mil (John N. Hodges)

In article smu@ixnews2.ix.netcom.com, dionkk@ix.netcom.com (Dion Kurczek)

writes:

 >I had the same headaches with Delphi's MessageBox method.  I wound up

>writing my own wrapper around the standard Windows MessageBox function

>(defined in the WinProcs unit).  This was a much more satisfying

>solution.

>

[nice code deleted]

Note that MessageBoxis not a Delphi specific call, but a Windows API call.

Did you check out Delphi's MessageDlg call?  Very similiar to what you wrote.

---

*   LT Nick Hodges, USN                     Naval Postgraduate School

*

*   jnhodges@nps.navy.mil                Information Technology Management

*

*   CIS: 71563,2250 AOL: NHodges                   Monterey, CA

*

*   The opinions expressed above are entirely my own and not the Navy's.

*

*   Visit my homepage:  http://vislab-www.nps.navy.mil/~jnhodges

*

From: jnhodges@nps.navy.mil (John N. Hodges)

In article F04@eskimo.com, mcmillan@eskimo.com (Gary L. McMillan) writes:

>I'm not having any luck using a string variable in the text

>parameter of a MessageBox Method in Delphi. I can use real text

>successfully, but not a variable. What am I missing?

>

MessageBox is a Windows API call that expects a PCHAR type as the string

variable.

The more "Delphi" wa y is to use the MessageDlg call.

---

*   LT Nick Hodges, USN                     Naval Postgraduate School

*

*   jnhodges@nps.navy.mil                Information Technology Management

*

*   CIS: 71563,2250 AOL: NHodges                   Monterey, CA

*

*   The opinions expressed above are entirely my own and not the Navy's.

*

*   Visit my homepage:  http://vislab-www.nps.navy.mil/~jnhodges

*


Delphi hates PCTools for Windows 2.0

#1031.FAQ	From: alb@xetron.com (Al Brunck)

In article <3jpok4$1cp@dsk92.itg.ti.com>, robertw@skeeter.itg.ti.com

says...

>

>I just received my copy of Delphi and spent last night installing it

>and playing around.  One sad thing I discovered is that Delphi can't

>seem to handle having PC Tools for Windows 2.0 as the shell.

>

>Delphi seems to work OK until you pause and try to restart a program.

>I started Delphi, got the (blank) form and clicked on the Run button.

>The project compiled and started running.  I then clicked on the Pause

>button.  Everything seemed fine.  When I clicked on the Run button

>again to continue the program, I got the following message in a gray

>"Error" window:

>

>        Project Project1.exe raised exception class EGPFault with

>        message "General Protection Fault in module PASDBK16.DLL

>        at 000F:115C"  Process stopped.  Use Step or Run to continue.

>

>So I click on the Run button again and got pretty much the same message

>in a white window.  I click on OK and project1.exe terminates and I'm

>back in the Delphi IDE as if nothing has happened.  It's nice that

>I didn't have to restart Windows, but this will make debugging my

>programs rather difficult.

>

>When I went back to ProgramManager as my shell (yuck) the EGPF problem

>went away.

>

>My system:  486DX2 @66, 16M ram, Windows 3.11 (not WFWG), SB16 w/cdrom.

>

>Does anyone have any clues about why Delphi is having a problem with PCTW?

>I *really* don't want to give either one up, but since no other app

>development system I use has any trouble with PCTW, I have to point the

>finger at Delphi.

>

>Any patches out there yet?

>

>Robert Wallace

>robertw@metronet.com

I had a similar problem, but I'm running Windows 95 (Beta), not PC Tools.

When I paused the Text Editor demo program, I got a divide by zero fault

message in USER.EXE.  Kind of makes debugging difficult.

From: robertw@skeeter.itg.ti.com (Robert Wallace)

Marcy Jackson (mjjacks@ix.netcom.com) wrote:

: I was going to upgrade to VB3.0 pro until so many VB programmers talked

: me into Delphi.  However, I can hardly imagine giving up PCTW.  I found

: the following post informative and I hope Robert Wallace doesn't mind me

: reposting it.  The post was originally on comp.lang.basic.visual.misc.

: In <3kkl0j$7oi@dsk92.itg.ti.com> robertw@skeeter.itg.ti.com (Robert

: Wallace) writes:

[ most text deleted ]

: >A Borland employee (who shall remain nameless, unless he speaks up)

: >sent me email stating, and I paraphrase, PCTW uses hardware interrupts

: >1 and 3 without restoring certain registers, so the Delphi debugger

: >(and other Borland debugging tools) which uses the same hardware

: >interrupts, doesn't have all the info it needs.  Both Borland and

: >Semantec seem to be aware of the problem, but no fixes are currently

: >available -- Borland can't and Semantec won't.

While the UBE (unnamed Borland employee) wrote "hardware interrupts 1 and 3"

I believe he meant "software interrupts 1 and 3".

Can anyone tell me what PCTW needs with these interrupts?

Robert Wallace

robertw@metronet.com

From: jazzbeau@netcom.com (Steve Barnette)

I think your look at the wrong program being at fault. I had to quit

using PC-Tools for Windows because  it crashed my development system

running the Windows debug kernal all the time. PCTW isn't exactly robust.

Steve B.

Robert Wallace (robertw@skeeter.itg.ti.com) wrote:

: I just received my copy of Delphi and spent last night installing it

: and playing around.  One sad thing I discovered is that Delphi can't

: seem to handle having PC Tools for Windows 2.0 as the shell.

: Delphi seems to work OK until you pause and try to restart a program.

: I started Delphi, got the (blank) form and clicked on the Run button.

: The project compiled and started running.  I then clicked on the Pause

: button.  Everything seemed fine.  When I clicked on the Run button

: again to continue the program, I got the following message in a gray

: "Error" window:

:       Project Project1.exe raised exception class EGPFault with

:       message "General Protection Fault in module PASDBK16.DLL

:       at 000F:115C"  Process stopped.  Use Step or Run to continue.

: So I click on the Run button again and got pretty much the same message

: in a white window.  I click on OK and project1.exe terminates and I'm

: back in the Delphi IDE as if nothing has happened.  It's nice that

: I didn't have to restart Windows, but this will make debugging my

: programs rather difficult.

: When I went back to ProgramManager as my shell (yuck) the EGPF problem

: went away.

: My system:  486DX2 @66, 16M ram, Windows 3.11 (not WFWG), SB16 w/cdrom.

: Does anyone have any clues about why Delphi is having a problem with PCTW?

: I *really* don't want to give either one up, but since no other app

: development system I use has any trouble with PCTW, I have to point the

: finger at Delphi.

: Any patches out there yet?

: Robert Wallace

: robertw@metronet.com

--

______________________________________________________________________________

_

FCS Systems Inc.

jazzbeau@netcom.com

   A nod is as good as a wink to a blind horse.


Winsock via DELPHI

#1032.FAQ	From: dmurdoch@mast.queensu.ca (Duncan Murdoch)

In article <NEWTNews.795424072.11813.kevinb@worf> Kevin Bonifield

<kevinb@spacecom.com> writes:

>Has anyone used Winsock.dll functions from DELPHI?

>It seems like it would be easy to call them (from

>an external DLL) but would require porting the

>winsock.h header from C to PASCAL.

>Anyone interested in starting such a project with me?

>I am strong with C, mediocre with PASCAL....but I am hooked

>on DELPHI!  ps - please email me a copy of your post if responding.

You should read this newsgroup, not just post to it.  There have been several

messages about this.

PASOCK10.ZIP is available in several places, including CICA and Simtel20.

It's a port of the winsock.h header file to Pascal (with a few minor errors

and omissions connected with the inet_addr function).  It was written for

BP/TP, but works fine in Delphi.

A couple of people have said they're working on a Delphi component to

encapsulate it in a nice way.  I don't think any of those have been published

yet.

Duncan Murdoch

From: The Green Meddler <kilgalen@tde.com>

dmurdoch@mast.queensu.ca (Duncan Murdoch) wrote:

>

> PASOCK10.ZIP is available in several places, including CICA and Simtel20.

> It's a port of the winsock.h header file to Pascal (with a few minor errors

> and omissions connected with the inet_addr function).  It was written for

> BP/TP, but works fine in Delphi.

>

> A couple of people have said they're working on a Delphi component to

> encapsulate it in a nice way.  I don't think any of those have been

published

> yet.

>

> Duncan Murdoch

and Tom Cabanski's quick port to delphi is available on:

ftp.netcom.com /pub/ic/ice-floe winsock.zip

GM


What are and how do I use pointers?

#1033.FAQ	From: ts@uwasa.fi (Timo Salmi)

A draft for an addition to my TP FAQ:

74. *****

 Q: What are and how do I use pointers?

 A: This is a beginner's simplified introduction. Consider the

following example

  {$M 16384,0,80000}

  var yPtr : ^real;

  begin

    New(yPtr);

    yPtr^ := 3.14159;

    writeln ('2 times pi = ',  2.0 * yPtr^);

    Dispose(yPtr);

    yPtr := nil;

  end.

Before we can discuss pointers we have to consider some rudiments of

what a kind of a memory model a compiled Turbo Pascal program uses.

This is a highly simplified presentation. For a more detailed

presentation of the TP memory model see for example Tischer (1990b).

  +-------------------------+

  | Heap                    |

  |-------------------------|

  | Data Segment            |

  |-------------------------|

  | Code                    |

  |-------------------------|

  | Program Segment Prefix  |

  +-------------------------+

When you write and compile a Turbo Pascal program it usually

consists of (this is a simplification!) of the three lowest parts.

When you define a global variable, it goes to the Data Segment. For

example defining at the beginning of your program

 var x : real;

requires 6 bytes from the data segment. (Local variables are placed

on the stack.)

   Now, the catch is that because of the underlying 16-bit nature of

MS-DOS, the size of the data segment cannot exceed 64Kb. On occasion

the 64Kb is insufficient. However, if you use pointers, the

corresponding variable values are held on the heap instead of the

data segment or the stack. Before you can use the heap, you have to

reserve it for your program. The following compiler directive makes

a heap of 80000 bytes available to your program {$M 16384,0,80000}.

(The syntax is {$M Stack size, Low heap limit, High heap limit}).

   With pointers you do not refer to a variable directly, but you

point to it. For example, define

  var yPtr : ^real;

Before you can use this pointer, you have to create this new dynamic

variable as follows:

  New(yPtr);

The New(yPtr) statement "Creates a new dynamic variable and sets a

pointer variable to point to it." This pointer, yPtr, will point to

the actual value, which the program puts on the heap. In your

program you can write, for example

  yPtr^ := 3.14159;

Think about the difference between yPtr and yPtr^. The former

contains the value of the memory address where you now have put the

value 3.14159. The latter gives that value. From you point of you it

can be used like any ordinary real variable. The difference is that

it is on the heap not on the data segment (or stack). Thus you can

now use this pointer. For example you n write

 writeln ('2 times pi = ',  2.0 * yPtr^);

When you do not need the pointer any more in your program you can

dispose of it to release the memory allocated for other purposes:

  Dispose(yPtr);

  yPtr := nil;

"After a call to Dispose, the value of yPtr is undefined and it is

an error to reference yPtr. The reserved word nil denotes a pointer

type constant that does not point to anything." Setting yPtr := nil

is just good programming practice, because then you can later easily

test whether the pointer is available or not. Disposing of a pointer

within your program is not necessary unless the amount of memory is

a critical consideration in your program. The heap will be released

when your program terminates.

  To recount. What yPtr actually contains is the memory address of

the value on the heap. When you write yPtr^, the caret indicates

that you do not mean the pointer itself, but the pointed memory

location in the heap. In this example that memory location in the

heap was made to contain 3.14159.

   You can also define the pointer types. Our second example

illustrates. It displays the squares from one to ten.

  {$M 16384,0,80000}

  type arrayType = array [1..10] of real;

  type arrayPtrType = ^arrayType;

  var A : arrayPtrType;

      i : integer;

  begin

    if SizeOf(arrayType) > MaxAvail then begin

      writeln ('Out of memory');

      halt;

    end;

    New(A);

    for i := 1 to 10 do A^[i] := i*i;

    writeln (A^[9]);

  end.

For an actual application using pointers, see the item "How can I

copy a file in a Turbo Pascal program?"

   All the best, Timo

..................................................................

Prof. Timo Salmi      Co-moderator of comp.archives.msdos.announce

Moderating at garbo.uwasa.fi anonymous FTP archives  193.166.120.5

Department of Accounting and Business Finance; University of Vaasa

Internet: ts@uwasa.fi   BBS +(358)-61-3170972; FIN-65101,  Finland


What are interrupts?

#1034.FAQ	From: ts@uwasa.fi (Timo Salmi)

In article <reza.794517305@njmsa> reza@njmsa.UMDNJ.EDU (Syed Reza) writes:

:I am using TP 6.0 and trying to learn as much about it. I noticed there

:are a several commands involving interrupts and I would like to learn how

:to use them.

You'll find the information in the following file of interest

 76384 Jan 26 23:24 garbo.uwasa.fi:/pc/ts/tsfaqp22.zip

 tsfaqp22.zip Common Turbo Pascal Questions and Timo's answers

"If you do not know how to go about getting this material, users are

welcome to email me for the prerecorded garbo.uwasa.fi instructions

(long, circa 29Kb). If you do not receive my reply within five days,

please ask your own site's system manager to construct a returnable

mail path for you".

   All the best, Timo

..................................................................

Prof. Timo Salmi      Co-moderator of comp.archives.msdos.announce

Moderating at garbo.uwasa.fi anonymous FTP archives  193.166.120.5

Department of Accounting and Business Finance; University of Vaasa

Internet: ts@uwasa.fi   BBS +(358)-61-3170972; FIN-65101,  Finland


Delphi Screen Parameters

#1035.FAQ	From: villalon@crl.com (Craig)

In article <D5np47.KMM@eskimo.com>, mcmillan@eskimo.com says...

>

>Using this to center an object on a form:

>

>Button1.Left := (Form1.Width - Button1.Width) div 2;

>Button1.Top := (Form1.Height - Button1.Height) div 2;

>

>I find that the horizontal centering of the object roughly correct, but

>the vertical centering is off by about 30% - can anyone explain why?

  Use the forms ClientHeight and ClientWidth properties instead.

--

--

Craig Villalon

internet: villalon@crl.com


ExitWindows(0, wrongcodes)

#1036.FAQ	From: gfinney@comp.uark.edu (Greg Finney)

jeffrey.huck@m.cc.utah.edu (Jeffrey Huck) writes:

>Anyway...  The documentation and the Win31 unit both give the wrong codes for

>EW_RESTARTWINDOWS ($42) and EW_REBOOTSYSTEM ($43).  Anyone know what there

>supposed to be?  Or how to accomplish this by other means?  I've managed to

>get a Restart by using ExitWindowsExec('','') but I'd like a more proper

>method, and a way to reboot the entire system.

I use:

  ew_ExitWindows    = $0000;

  ew_RestartWindows = $0042;

  ew_RebootSystem   = $0043;

Along with:

  ExitWindows(ew_RestartWindows,0);

etc. and it seems to work fine.

--

Greg Finney            |  Jer 33:3 The Lord says...'Call to me

gfinney@comp.uark.edu  |  and I will answer you, and tell you

Dept. of Physics       |  great and unsearchable things you

University of Arkansas |  do not know.'

From: jeffrey.huck@m.cc.utah.edu (Jeffrey Huck)

>

>Along with:

>

>  ExitWindows(ew_RestartWindows,0);

>

Thanks.  Seems the doc's just listed the paramaters in reverse order.  Stupid

me thought to try every hex code instead of just switching the params around.

 Go figure.

Jeffrey Huck

jeffrey.huck@m.cc.utah.edu

---Sig still under repair---


How do I run my app minimized??

#1037.FAQ	From: Greg Dunlap <gdd@tezcat.com>

>

> One thing I can't figure out is how to get a Delphi app to respect the

> Windows show command.  What I mean is, if I run my app with the "Run

> Minimized" box checked, it should start as an icon... but it doesn't.

> In C, you'd use the nShowCmd argument of WinMain, but I can't find

> anything like that in Delphi.

>

> I've tried obvious things like changing the Position property but to

> no avail.  How the heck do I do this?

If you want the app to run minimzed, create an OnCreate event handler

for the form and add the following code:

WindowState = wsMinimized;

You're rollin.

GDD

From: nathans@teleport.com (Nathan Silva)

In article <3khlth$2lq@quilla.tezcat.com>, Greg Dunlap  <gdd@tezcat.com>

wrote:

>

>If you want the app to run minimzed, create an OnCreate event handler

>for the form and add the following code:

>

>WindowState = wsMinimized;

Okay, but how would I let Windows/the user decide?  Try this:

  - Put a Delphi-generated app in your Windows StartUp group.

  - Check the "Run Minimized" box.

  - Run the application.

It doesn't work.  The program only runs the way it's been hard-coded to

run and it ignores the nShowCmd argument that's passed by Windows.

--

--

  Nathan Silva

  Matrix Software Solutions, Portland, Oregon, USA

  E-Mail: nathans@mtrx.com / Fax: 503-797-0374 / Voice: 503-731-9174

From: dmurdoch@mast.queensu.ca (Duncan Murdoch)

In article <3khp0d$gk4@linda.teleport.com> nathans@teleport.com (Nathan Silva)

writes:

>Okay, but how would I let Windows/the user decide?  Try this:

>  - Put a Delphi-generated app in your Windows StartUp group.

>  - Check the "Run Minimized" box.

>  - Run the application.

>It doesn't work.  The program only runs the way it's been hard-coded to

>run and it ignores the nShowCmd argument that's passed by Windows.

The CmdShow variable in the System unit contains the value that was passed in.

I'm not sure if Delphi pays attention to it or not, but if it doesn't, you

could put in your own test in the application OnCreate event.

Duncan Murdoch

From: nathans@teleport.com (Nathan Silva)

In article <dmurdoch.1672.2F6C714E@mast.queensu.ca>,

Duncan Murdoch <dmurdoch@mast.queensu.ca> wrote:

>The CmdShow variable in the System unit contains the value that was passed

in.

>I'm not sure if Delphi pays attention to it or not, but if it doesn't, you

>could put in your own test in the application OnCreate event.

Thank you, it works great.  No wonder I couldn't find it in the Application

object, where it belongs!

--

--

  Nathan Silva

  Matrix Software Solutions, Portland, Oregon, USA

  E-Mail: nathans@mtrx.com / Fax: 503-797-0374 / Voice: 503-731-9174

From: jnhodges@nps.navy.mil (John N. Hodges)

Subject: Re: Delphi: How do I run my app minimized?

Date: 20 Mar 1995 22:58:42 GMT

In article gk4@linda.teleport.com, nathans@teleport.com (Nathan Silva) writes:

>In article <3khlth$2lq@quilla.tezcat.com>, Greg Dunlap  <gdd@tezcat.com>

wrote:

>>

>>If you want the app to run minimzed, create an OnCreate event handler

>>for the form and add the following code:

>>

>>WindowState = wsMinimized;

>

>Okay, but how would I let Windows/the user decide?  Try this:

>

>  - Put a Delphi-generated app in your Windows StartUp group.

>  - Check the "Run Minimized" box.

>  - Run the application.

>

>It doesn't work.  The program only runs the way it's been hard-coded to

>run and it ignores the nShowCmd argument that's passed by Windows.

>

There is a way to fix this, and I willtry to track down and post the code.

The "problem" occurs because the main form is not the apps amin Window.

TApplication is the main Window and it is a zero sized Window that

does all the work as far as Windows is concerned.  you have to redirect the

minimize command from progman or whatever to it.

---

*   LT Nick Hodges, USN                     Naval Postgraduate School

*

*   jnhodges@nps.navy.mil                Information Technology Management

*

*   CIS: 71563,2250 AOL: NHodges                   Monterey, CA

*

*   The opinions expressed above are entirely my own and not the Navy's.

*

*   Visit my homepage:  http://vislab-www.nps.navy.mil/~jnhodges

*

From: victorddm@delphi.com

Subject: Re: Delphi: How do I run my app minimized??

Date: Mon, 20 Mar 95 22:44:57 -0500

Nathan Silva <nathans@teleport.com> writes:

>One thing I can't figure out is how to get a Delphi app to respect the

>Windows show command.  What I mean is, if I run my app with the "Run

>Minimized" box checked, it should start as an icon... but it doesn't.

>In C, you'd use the nShowCmd argument of WinMain, but I can't find

>anything like that in Delphi.

>

>I've tried obvious things like changing the Position property but to

>no avail.  How the heck do I do this?

Nathan,

In you Form OnCreate event, put this:

  ShowWindow(Handle, CmdShow);

Enjoy it,

--Victor J. DuLuc


Current directory/drive ?

#1038.FAQ	From: Greg Dunlap <gdd@tezcat.com>

>       I've been making my first attempt at creating/writing .INI files.

> The only way I can find to get the current directory/drive id to create a

> directory and drive list box and derive the appropriate label from those

> objects. At this point I have usable info. Another oddity I found was that

> I couldn't directly assign btnButton1.Caption :=

> DirectoryListBox1.DirLabel. I got a type mismatch. I can pass the DirLabel

> to lblLabel1.Caption and from lblLabel1.Caption to btnButton1.Caption.

> What's the difference.

>

The problem is that the DirLabel is of type TLabel and a button's caption

is of type string. There's something going on with the DirLabel

which allows it to be a label's caption. To quote from Delphi online

help:

"The DirLabel property provides a simple way to display the current

directory as the caption of a label control. When the current directory

changes in the directory list box, the change is reflected in the caption of

the label.

Specify the label you want updated with the current directory as the value

of the DirLabel property."

However, since all TLabels do have a caption property, you can write

the following line of code which should solve your problem:

btnButton1.Caption := DirectoryListBox1.DirLabel.Caption;

Hope that wasn't too obtuse or confusing :)

GDD

gdd@tezcat.com

Kallista, Inc

Chicago, IL

From: jnhodges@nps.navy.mil (John N. Hodges)

Subject: Re: Delphi: Current directory/drive ?

Date: 20 Mar 1995 22:55:54 GMT

In article 5FJ@eskimo.com, mcmillan@eskimo.com (Gary L. McMillan) writes:

>       I've been making my first attempt at creating/writing .INI files.

>The only way I can find to get the current directory/drive id to create a

>directory and drive list box and derive the appropriate label from those

>objects. At this point I have usable info. Another oddity I found was that

>I couldn't directly assign btnButton1.Caption :=

>DirectoryListBox1.DirLabel. I got a type mismatch. I can pass the DirLabel

>to lblLabel1.Caption and from lblLabel1.Caption to btnButton1.Caption.

>What's the difference.

>

To read/write INI files, check out the TInifile object

Something like this

var

      MyIniFile: TIniFile;

begin

     MyIniFile := tinifile.Create;

     MyIniFile.ReadString(   [parameters]        );

     MyInifile.WriteString(....);

     MyInifile.free;

end;

There are methods for Write/ReadBool and Write/ReadInt, among others

---

*   LT Nick Hodges, USN                     Naval Postgraduate School

*

*   jnhodges@nps.navy.mil                Information Technology Management

*

*   CIS: 71563,2250 AOL: NHodges                   Monterey, CA

*

*   The opinions expressed above are entirely my own and not the Navy's.

*

*   Visit my homepage:  http://vislab-www.nps.navy.mil/~jnhodges

*


Properties by name?

#1039.FAQ	From: dmurdoch@mast.queensu.ca (Duncan Murdoch)

In article <629060143wnr@landscap.demon.co.uk> Marc@landscap.demon.co.uk (Marc

Palmer) writes:

>Is it possible to get and set properties on Delphi components at

>run-time using their name?

Yes, using the services provided by the Typinfo unit you can find out about

the type and values of published properties.  This is what the Object

Inspector uses.

Duncan Murdoch

From: victorddm@delphi.com

Duncan Murdoch <dmurdoch@mast.queensu.ca> writes:

>Yes, using the services provided by the Typinfo unit you can find out about

>the type and values of published properties.  This is what the Object

>Inspector uses.

Duncan,

I've being playing with it without much result because lack of documentation.

Do you know of any document/white paper on using Typinfo and Prop???.

May be calling Borland will they make it available?

This is a powerful gun.

Thanks,

--Victor J. DuLuc

From: tax@clark.net (Tax Analysts)

Marc Palmer (Marc@landscap.demon.co.uk) wrote:

: Is it possible to get and set properties on Delphi components at

: run-time using their name? Here's what I mean:

:   UnknownComponent.SetProperty('Caption', newcapt); { is there a way

:                                                     to do this ? }

: { And also something like this... }

:   oldleft := UnknownComponent.GetProperty('Left').AsInteger;

: end;

Yipes, macro expansion a la Clipper.  Watch the .EXE size *really*

grow, in that case, no?

Kendall (speculating)

From: Marc@landscap.demon.co.uk (Marc Palmer)

In article: <x+-42du.victorddm@delphi.com>  victorddm@delphi.com writes:

>

> I've being playing with it without much result because lack of

documentation.

> Do you know of any document/white paper on using Typinfo and Prop???.

> May be calling Borland will they make it available?

Me too. What are the classes/functions and what do they do? I loaded the

TYPINFO.DCU into the editore and couild pick out some names among the

garbage. I still have no idea what they do!

> This is a powerful gun.

You're telling me! You'd need some sort of

UnknownComponent.HasProperty('Caption')

function to tell is a property exists. I suspect this is all inside

Delphi already. I suppose there might be a conflict with Borland, in

that it would be quite easy to create your own OO langauge development

environment like this!

********************************************************************

* Marc P.                               E-Mail me for PGP 2.6 key  *

********************************************************************


10 REASONS to use Delphi

#1040.FAQ	From: ejv@ix.netcom.com (Earl Vincent)

In <D5qwn2.Fp0@bull.nl> mvnassou@spar.bull.nl (Martin van Nassou)

writes:

>

>Needed: 10 Reasons why I MUST use Delphi (to convince my manager)!

>

>Please send your replies to this newsgroup, because this is not my

account.

>

>Thanks!

>

>Coen Willemse

>

>

Here's a few reasons why I like Delphi:

1.  No P-Code (a real EXE)

2.  Faster application development time than VB (at least from my

    experience).  It takes me about 10 minutes now to create a free

    standing data base app.

3.  Use of Paradox & DBase tables (I have developed several app.'s in

    these products) without hassle

Earl Vincent

From: rloewy@panix.com (Ron Loewy)

In article <3kksrr$nfa@ixnews2.ix.netcom.com>, Earl Vincent wrote:

>

> In <D5qwn2.Fp0@bull.nl> mvnassou@spar.bull.nl (Martin van Nassou)

> writes:

>

> >

> >Needed: 10 Reasons why I MUST use Delphi (to convince my manager)!

> >

> >Please send your replies to this newsgroup, because this is not my

> account.

> >

> >Thanks!

> >

> >Coen Willemse

> >

> >

>

> Here's a few reasons why I like Delphi:

>

> 1.  No P-Code (a real EXE)

> 2.  Faster application development time than VB (at least from my

>     experience).  It takes me about 10 minutes now to create a free

>     standing data base app.

> 3.  Use of Paradox & DBase tables (I have developed several app.'s

in

>     these products) without hassle

>

> Earl Vincent

>

Here are some more :

4. The ability to create DLL's.

5. The ability to create components.

6. Object Oriented for better code re-use.

7. Your competitors will have it and will eat your lunch if you can

not compete on the same field <g>

Ron.

--

Ron Loewy

HyperAct, Inc. | rloewy@panix.com | (319) 351 8413

HLPDK/PA - Multi-Platform Hypertext Tool, Win/HTML/OS2/DOS

Interactive Help - Interactive and Dynamic WinHelp ext.

PASTERP - Extendable Application Script Language

From: John Lam <jlam@alchemy.chem.utoronto.ca>

>

> ----------------------------------------------------------------------

> Needed: 10 Reasons why I MUST use Delphi (to convince my manager)!

>

My $.02:

1.  Exception Handling- If you've ever tried to write a bullet-proof VB app

    you'll appreciate this the most!

2.  Component Building- The ability to inherit and modify *any* of the

    stock VCL components in Delphi without having to start from scratch

    is a big bonus.

    Case in point:  I wanted to add drag-and-drop ability

    to the TDBGrid component.  But it doesn't support the OnClick or

    OnMouseDown events that are necessary for processing the dmManual

    DragMode event (see page 376 in Delphi UG).  Simply inherit the TDBGrid

    component and add OnClick to the published properties list!  Takes

    *1 line* of 'code'!!  This would have been impossible to do in VB.

John Lam

From: Mark Johnson <cityzoo@mindspring.com>

rloewy@panix.com (Ron Loewy) wrote:

>

> In article <3kksrr$nfa@ixnews2.ix.netcom.com>, Earl Vincent wrote:

> >

> > In <D5qwn2.Fp0@bull.nl> mvnassou@spar.bull.nl (Martin van Nassou)

> > writes:

> >

> > >

> > >Needed: 10 Reasons why I MUST use Delphi (to convince my manager)!

> > >

> > >Please send your replies to this newsgroup, because this is not my

> > account.

> > >

> > >Thanks!

> > >

> > >Coen Willemse

8. Ability to dynamicly create controls (i.e. during runtime)

   and place them within other containers.

9. Delphi provides an open interface API for version control

   software and third party additions to the IDE.

10. Delphi provides the ultimate in code reusability: DLL's,

    components, form templates, application templates, etc.

______________________________________________________________________________

Mark R. Johnson   |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/

Atlanta, GA USA   |\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\

keeper@netcom.com |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/


Formless delphi application

#1041.FAQ	From: moscow@aed.org (Moscow)

Gary Witty (gwitty@newpop.sccsi.com) wrote:

: Is there a way to create a Delphi app with no form? All I want to do

: is respond to another app in this one, and no screen is necessary.

Just press Ctrl-F12 and click on project file, which in fact is

pascal program like:

program Project1;

uses

  Forms, ...;

begin

  Application.CreateForm(...

  ...

end.

Change uses clause to

  uses WinProcs, WinTypes, Messages;

or whatever units you need to use, remove all lines between begin and end,

and write your program as ordinary pascal program. :-)

If you need to write such programs often, put this project

into gallery.

Gorik

gorik@cs.msu.su (Gor V. Nishanov)


Normalized or Iconized?

#1042.FAQ	From: jnhodges@nps.navy.mil (John N. Hodges)

In article 4hf@newsbf02.news.aol.com, russchinoy@aol.com (RussChinoy) writes:

>>I'm writing a program where I have to know whether the

>>window

>>is Normal or Iconized. Delphi is stumbling here.

>>

>>If I start out with a normalized form and then iconize it,

>>both a glance

>>at form.WindowState and the API call IsIconic( hWnd ) tell

>>me

>>that the Window is Normal when it ain't.  (perhaps sometimes

>>it takes a

>>few minimize/maximize calls to throw it off).

>>

>>Therefore I can't tell when a user is clicking on a

>>minimized icon

>>and my program can't fulfill its functional requirements.

>>

Try IsIconic(Application.Handle).  the Application variable is actually the

thing

being displayed when the app is minimized.  Application is a Window of

zero size that is displayed when you minimize your app.  The main form

of your project is not the main Window of the application.  the TApplication

descendent defined in the *.DPR file is the main window.

---

*   LT Nick Hodges, USN                     Naval Postgraduate School

*

*   jnhodges@nps.navy.mil                Information Technology Management

*

*   CIS: 71563,2250 AOL: NHodges                   Monterey, CA

*

*   The opinions expressed above are entirely my own and not the Navy's.

*

*   Visit my homepage:  http://vislab-www.nps.navy.mil/~jnhodges

*


How to create Delphi TForm.Minimize

#1043.FAQ	From: bstowers@cybernetics.net (Brad Stowers)

Allen Stoner <astoner@iacc.messiah.edu> wrote:

>   I've got a BP7 app that I'm trying to convert to Delphi.  Most of it is

> comming okay, but there are a couple parts that I'm having problems with.

> 1.  When the main form is minimized I want to be able to clear the box on

> the form depending on an option.  As far as I can tell the TForm doesn't

have

> an OnMinimize event or method.  So my question is how can I add one?

>   The TApplication has a minimize method but I would prefer to do it on

> the form.  In this case could get away with minimizing the application

> but I might not always want to minimize the application.

Check out the OnResize event, or you may have to use a message handler for

WM_SIZE check the TWMSize.SizeType value.

> 2.  I also want the [ENTER] key to minimize the form.  In BP7 I overrode

> the WMChar method.  Can I do the same thing on the TForm?

Yes. OnKeyPress event.

> Just a comment about documentation.  I'm familiar with Borland Pascal,

> but Object Pascal is a little different but I can deal with that.  What I

> don't understand is why Borland is hampering a new user by not including

> the language reference guide.  I'm also not overly impressed by the

> online help.  It does work if you look long enough, of course there are

> also errors.  Has anyone seen the str example.  This one isn't even a new

> procedure.  It has been around for years and the example is wrong in the

> online help.

I don't know what they skimped, but I don't appreciate it at all.  Look at

TListBox compent help, the Properties popup has a list of all the props,

and not a damn one of them is linked.  Too many oversights, not enough

proof-reading went into this.

Regards,

Brad

--------------------------------------------------------

Brad Stowers             |  bstowers@cybernetics.net

deltaComm Development    |  My views are my own...

Telix for Windows & DOS  |  Keep yer hands off of 'em.

--------------------------------------------------------

      http://www.cybernetics.net/users/bstowers/


Delphi: version control program?

#1044.FAQ	From: Steve Teixeira <steixeir@borland.com>

tbradf@abcomp.win-uk.net (Antonia Bradford) wrote:

>

>

> In article <3kejvo$qgf@pipe3.pipeline.com>, Jin Mai (mwj@pipeline.com)

writes:

> >

> >Is there any source code version control program for

> >Delphi?

> >

> >--

> >Jin Mai        mwj@pipeline.com

> >

>

> The theory is that you use PVCS which you have to purchase

> seperately. Unfortunately, it is scandalously expensive - used to

> be really good value a few years ago. The Borland sales blurb for

> Delphi claims that the environment is open and you should be able

> to integrate other version control systems with it. So far I have

> not found any documentation which explains how to do this - hope

> someone works it out soon so we can start using GNU RCS instead -

> that is free :-)

>

The files that describe how to integrate your favorite version control

software

with Delphi are:

TOOLINTF.PAS

VCSINTF.PAS

VIRTINTF.PAS

EXPTINTF.PAS

ISTREAMS.PAS

Hope that helps.

        -Steve Teixeira

         steixeir@borland.com


Delphi-Mouse movement over control

#1045.FAQ	From: keeper@netcom.com (Mark R. Johnson)

In article <1995Mar24.073753.9798@lts.sel.alcatel.de>,

   sanz@sls812.NoSubdomain.NoDomain (Alfonso Sanz US/PAT #45021) wrote:

>Is there an event like in Paradox, that is called when entering and another

event whe leaving the control? I have just found an event for moving inside

the control.

>

>TIA

>Alfonso

Windows does not generally support entry and exit events.  Thus, neither

does Delphi.  You must 'simulate' your own.  For example, use the

OnMouseMove (or whatever it's called) handler for the button to

write your status bar message.  Use the form's MouseMove handler

to erase the status bar message.

Hope this helps.

______________________________________________________________________________

Mark R. Johnson   |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/

Atlanta, GA USA   |\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\

keeper@netcom.com |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/


Formated Memos in Delphi

#1046.FAQ	From: jleon@ix.netcom.com (John Leon)

In <1995Mar24.075550.13147@lts.sel.alcatel.de>

sanz@sls812.NoSubdomain.NoDomain (Alfonso Sanz US/PAT #45021) writes:

>

>In Paradox there exist a Database-type called Formated Memo. In this

Memo you can change with the right mouse button the font, color, etc. of

the contents of the Memo.

>

>2 Questions:

>

>1) Can I access to this field with delphi?

>2) Is there a control to show this formated memo and to fill the memo

like in paradox?

>

>bye

>

>Alfonso

>

I understand the FORMATTED memo fields are not accessible by Delphi.

--

* John C. Leon

* Capital Markets Technology

* Texas Commerce Bank, Houston, TX

* jleon@ix.netcom.com


Beep for me baby!!

#1047.FAQ	From: rworks@itsnet.com (Steve Peterson)

Doug Reinhart <reinhart@gate.net> wrote:

->OK I figure it went this way....Borland Delphi programming group puts in

->every multi-media bell and whistle they could think of.

->

->NO ONE would want to just make the speaker go -beep-, right...?

->

->Well I would.  Nothing on it in the manuals, and I'm not finding anything

->in the help files (although I may just not have hit the right search yet)

->under 'beep', 'tone', 'sound', even the old MessageBeep no longer exists.

->

->Delphi brought me back to Pascal after a long absence, so if I'm missing

->something really simple; try to break it to me gently, OK?

->

You need to call the MessageBeep routine in the Windows API.

First, make sure you use Winprocs in your unit.  Then

MessageBeep (-1);

will cause a standard beep to come from your speaker.

Steve

From: mobergru@oslonett.no (Rune Moberg)

In article <Pine.A32.3.91.950323143024.113725B-100000@hopi.gate.net>,

Doug Reinhart <reinhart@gate.net> wrote:

> OK I figure it went this way....Borland Delphi programming group puts in

> every multi-media bell and whistle they could think of.

>

> NO ONE would want to just make the speaker go -beep-, right...?

>

> Well I would.  Nothing on it in the manuals, and I'm not finding anything

> in the help files (although I may just not have hit the right search yet)

> under 'beep', 'tone', 'sound', even the old MessageBeep no longer exists.

MessageBeep is supposed to be part of the Win API...? If you have a sound-

card, then the messagebeep will use it instead, so perhaps your soundcard

isn't turned on for the moment?

  =======================================ftp to:==========================

-== R.Moberg, author of CD-Player Pro! = ftp.cica.indiana.edu            ==-

  =======================================/pub/pc/win3/sound/cdppro45.zip==

From: kvlahos@lbs.lon.ac.uk (Kiriakos Vlahos)

In article <Pine.A32.3.91.950323143024.113725B-100000@hopi.gate.net> Doug

Reinhart <reinhart@gate.net> writes:

>Subject: Delphi...(Beep for me baby!!)

>From: Doug Reinhart <reinhart@gate.net>

>Date: Thu, 23 Mar 1995 14:37:35 -0500

>OK I figure it went this way....Borland Delphi programming group puts in

>every multi-media bell and whistle they could think of.

>NO ONE would want to just make the speaker go -beep-, right...?

>Well I would.  Nothing on it in the manuals, and I'm not finding anything

>in the help files (although I may just not have hit the right search yet)

>under 'beep', 'tone', 'sound', even the old MessageBeep no longer exists.

Yes it does exist!  Just look for it in the help file.  It is just a call to

the WIN 3.1 API.  So you need to include the right units in the Uses section.


Tab contols missing from VCL Source?

#1048.FAQ	From: Steve Teixeira <steixeir@borland.com>

mreith@cse.unl.edu (Michael Reith) wrote:

>

> I just received the source code for the VCL controls yesterday.

> However, when I did the install the README.TXT file stated that

> the source for the TabSet and TabbedNotebook were not included

> in this release.  It then gave a fax number where I could request

> these "additional" files (which I of course did immediately).

>

> Does anyone know why Borland did this?  It doesn't seem reasonable

> that they would get into a situation where they would have to send

> out two disks and have to pay twice for shipping.

>

> Not really complaining, just curious.

>

For legal reasons, you must sign a release with Borland to obtain a copy

of the tabs.pas source file.  Contact Karen Rogers in Borland Corporate

Affairs by fax at 408-431-4147.

        -Steve Teixeira

         steixeir@borland.com

From: Steve Teixeira <steixeir@borland.com>

Marc@landscap.demon.co.uk (Marc Palmer) wrote:

>

> In article: <3kvme2$c2d@druid.borland.com>  Steve Teixeira

<steixeir@borland.com> writes:

> >

> >

> > For legal reasons, you must sign a release with Borland to obtain a copy

> > of the tabs.pas source file.  Contact Karen Rogers in Borland Corporate

> > Affairs by fax at 408-431-4147.

>

> Would you care to expand on that? What number do we call in the U.K.?

> I've just ordered the VCL source, if it is not complete surely I am

> being 'deceived' ?

>

Not being a lawyer, I'd actually rather leave the topic where it is.  :)

Fax to the same number from the uk.

        -Steve Teixeira

         steixeir@borland.com

From: Steve Teixeira <steixeir@borland.com>

Michael Slack <mgslack@rsoc.rockwell.com> wrote:

>

> Steve Teixeira <steixeir@borland.com> wrote:

> >

> > mreith@cse.unl.edu (Michael Reith) wrote:

> > >

> > > I just received the source code for the VCL controls yesterday.

> > > However, when I did the install the README.TXT file stated that

> > > the source for the TabSet and TabbedNotebook were not included

> > > in this release.  It then gave a fax number where I could request

> > > these "additional" files (which I of course did immediately).

> > >

> >

> > For legal reasons, you must sign a release with Borland to obtain a copy

> > of the tabs.pas source file.  Contact Karen Rogers in Borland Corporate

> > Affairs by fax at 408-431-4147.

> >

> >     -Steve Teixeira

> >      steixeir@borland.com

>

> Another curious question.  Is there a voice phone number and/or

> an e-mail address we can use to contact Karen?

>

>                              Mike

Fax is best because we need to get a signature.

        -Steve Teixeira

         steixeir@borland.com


SQL: SELECT COUNT

#1049.FAQ	From: Grant Carpenter

>  2. When I do a query using SELECT COUNT(..... where is the result of the

>     count returned? Is it in Queryname.Params[0] ?

2. Shouldn't it be in TQuery.Fields[n], n being the number of the field in the

answer table?

Grant Carpenter

+++++++++++++++++++++++++++++++++++

grant@pinadvgrp.com

gcarpent@interserv.com

pinnacleMA@aol.com


Can we use TDW from BP7 with Delphi?

#1050.FAQ	From: Steve Teixeira <steixeir@borland.com>

mfrisch@wink.io.org (Mike Frisch) wrote:

>

>       I am curious to know if it's possible to use TDW from BP7 with

> Delphi and if so, how does one configure Delphi to work with it?  I

> turned on all debugging info in Delphi, but when I load the executable in

> TDW, it reports that the program has no symbol table.  Any ideas?

>

Won't work.  Not only is the symbol info different, but only the latest (4.6)

version of the debugger understands Delphi properties.

        -Steve Teixeira

         steixeir@borland.com

From: Steve Teixeira <steixeir@borland.com>

m.a.vaughan@larc.nasa.gov (Mark Vaughan) wrote:

>

> In article <3kse89$q5o@druid.borland.com> Steve Teixeira

<steixeir@borland.com> writes:

> >From: Steve Teixeira <steixeir@borland.com>

> >Subject: Re: Can we use TDW from BP7 with Delphi?

> >Date: 23 Mar 1995 18:22:01 GMT

>

> >mfrisch@wink.io.org (Mike Frisch) wrote:

> >>

> >>       I am curious to know if it's possible to use TDW from BP7 with

> >> Delphi and if so, how does one configure Delphi to work with it?  I

> >> turned on all debugging info in Delphi, but when I load the executable in

> >> TDW, it reports that the program has no symbol table.  Any ideas?

> >>

>

> >Won't work.  Not only is the symbol info different, but only the latest

(4.6)

> >version of the debugger understands Delphi properties.

>

> Hmmm...and how might one obtain this little jewel?  Is it sold as a

> stand-alone product, or does it only come bundled with another language

> product?

>

Call the Order Desk at 1-800-331-0877 and ask for the Delphi version of TDW.

        -Steve Teixeira

         steixeir@borland.com


Delphi & Bound Data Controls

#1051.FAQ	From: koterski@genghis (Steve Koterski)

dcjoerob@prime.planetcom.com wrote:

: I'm new to Delphi and visual programming.  How do bound data controls

: interact with Delphi.

: I seen some messages that indicate that they either have to be handled

: differently with Delphi or not used at all.

: Any information or insight that can be provided would be greatly

: appreciated.

In Delphi, you have two basic sets of similar controls, one set that is

data-aware and one that is not (essentially standard Windows controls).

The data-aware controls (Edit fields, Listboxes, Comboboxes, etc) are

all automatically updated when a row from the connected table is updated.

This happens through the TDataSource component, which is in turn connected

to a TTable component. Basically, the TDataSource component is the auto-

mated conduit between the table (represented by the TTable component) and

the data-aware controls.

The dynamic linking is established between these three objects by:

1. Setting the DataSource property of each control to point to the

   TDataSource component on the Form that will fill the control.

2. Setting the DataSet property of the TDataSource component to point to

   the TTable component on the Form that is to supply the data (a TQuery

   component may take the place of a TTable, here).

3. Setting the DatabaseName and TableName properties of the TTable comp-

   onent to the desired database and table, respectively.

4. And lastly, setting the Active property of the TTable to True. On doing

   this last setting, the data appears, and is automatically updated as

   the record/row in the table changes.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


Playing .wavs

#1052.FAQ	From: koterski@genghis (Steve Koterski)

Roderick Gammon (luoai@spy.org) wrote:

First, you cannot use a Delphi string as the parameter for the name of

the WAV file when calling the sndPlaySound API function. Instead, you

need a pointer to a null-terminated string. You then use the StrPCopy

command to copy the string (as in the selected value from a ListBox or

Edit component) into the array.  Here's an example:

   TForm1.PlayClick(Sender: TObject);

   var

     FileName: array[0..255] of Char;

   begin

     StrPCopy(FileName, FileListBox1.Items[FileListbox1.ItemIndex]);

     sndPlaySound(FileName, 1);

   end;

To make the sndPlaySound function available, you need to include the

MMSystem unit in the Uses section of the calling unit.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


Autofilling a TBListBox

#1053.FAQ	From: koterski@genghis (Steve Koterski)

Simon Love (csi063@coventry.ac.uk) wrote:

[...]

: I have written code to fill a list box with data elements from a table ( had

: to hand code it, couldn't find anything like an autofill list box attatched

: to a database field, and the TBListBox did not seem to do what I wanted ?! )

Have you looked at the TDBLookupList component, a data-aware component

designed to serve a a supplier of looked-up data? Even if this component

as-supplied does not provide the exact functionality you need, remember

that you can sub-class this object and incorporate your own operations.

: I have written an OnDblClick method to reference the item selected.

: I can retreive this string, but I cannot display what it was in a messagebox

: as it requires a sting of type PChar.

: The question is how to I make the string obtained from a list box into type

: PChar so I can pass it to the messagebox.

First, you can use Delphi strings with the MessageDlg function, the built-in

equivalent to the Windows MessageBox, without any need to transfer the

string value into a PChar.

Here's an example showing how to create the PChar if you must use the

Windows API function MessageBox:

   procedure TForm1.Blah;

   var

     p: PChar;

     Name: String[30];

     Size: Byte;

   begin

     Size := sizeof(Name);

     Inc(Size);

     GetMem(p, Size);

     .

     . call to MessageBox

     .

     FreeMem(p, Size);

   end;

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

From: pp000661@pop3.interramp.com (Robert Fabiszak)

In article <3kriit$oq0@rowan.coventry.ac.uk>, csi063@coventry.ac.uk says...

>

>

>

>The question is how to I make the string obtained from a list box into type

>PChar so I can pass it to the messagebox.

>

>I have made up an example below ...

>

>procedure TListBox....OnDblCkick

>var

>        word : String;

>begin

>

>        { Please allow for any errors .... just trying to get the idea across

}

>        word := ListBox1.Items[ListBox1.ItemIndex];

>

>        <<<< Error on next line - Incompatible types .. >>>>

>        Application.MessageBox(word, 'You Selected :',mb_ok);

>end;

>

Add a variable to the variable declarations section for your PChar, e.g.

   var

      szSelected: array[0..256] of char;

Then, use the StrPCopy function to copy your listbox string to the PChar:

   StrPCopy(szSelected, word);

In addition, you could have used the MessageDlg function, which accepts

Pascal-style

strings (but there you're limited as to what you can put in the message box

caption).

Hope this helps,

Bob


Error creating process?

#1054.FAQ	From: vic@wink.io.org (Vic Metcalfe)

OK, I've done some investigation, and here's what I've found...

: Has anyone else seen this and figured out what it means?

I think you get "Could not run/step the process" when one of the DLLs didn't

load successfully.  It turned out that if I commented a line that set the

Connected propery to a TDatabase to true in the initialization of a DLL

the problem went away.  I moved the initialization code to a separate function

and called it first thing in my program, and the problem stayed solved,

and the connect happens OK.

: Does anyone know what an internal windows error 15 is?

My guess is that this means that the module is already running.  I didn't

check, but I think that the main module of my program was hanging around

in memory, and then restarting it caused the error 15.

Regards,

  Vic.


ScrollBox1.HorzScrollBar changed?

#1055.FAQ	From: jleon@ix.netcom.com (John Leon)

In <8A623E6.109F0038C8.uuout@dkb.dk> jakob.paikin@dkb.dk (JAKOB PAIKIN)

writes:

>The real difficulty is to determine when ScrollBox1.HorzScrollBar has

>changed, since there is no onScroll/onChange event for a scrollbox.

>

>I hope this makes sense and that someone can come up with a

>solution/suggestion.

>

>

>Greetings from Denmark,

>

>+---------------------+-----------------------------+

>| Jakob Paikin        | E-mail: jakob.paikin@dkb.dk |

>| Copenhagen, Denmark | Fidonet: 2:235/208.15       |

>+---------------------+-----------------------------+

Dunno about the rest of your questions, but Windows itself very

definitely provides the mechanism for picking up the scrollbar events.

You may have to use the API to have the scroll control send a message to

your other controls.  In other words, you may have to get your hands

dirtier than merely adding code to an existing event handler.  If you

have the VCL source code, you might browse it to see what's going on.

Much of the time a simple descendant component can be written in a few

minutes to handle special needs.  Just this week I wrote my own

component for a very specific need ... less than 10 lines of code.

However, the VCL source was almost mandatory to find the private and

protected members of the ancestor object and how they were used.  I *did

NOT* have to modify Borland's code ... only add to it.  That's the

beauty of Delphi!

--

* John C. Leon

* Capital Markets Technology

* Texas Commerce Bank, Houston, TX

* jleon@ix.netcom.com


Delphi and Files

#1056.FAQ	From: jleon@ix.netcom.com (John Leon)

In <3l2fgb$khe@newsbf02.news.aol.com> digallery@aol.com (DIGallery)

writes:

>

>I have done considerable experimentation with Delphi using most of the

>built-in components and such. I feel ready to begin developing some

simple

>applications for my own use which need to do some file I/O. But I can

not

>seem to find any reference to opening and reading and writing files! I

>have noticed the class TStream but cannot find any doc on it anywhere.

Am

>I missing something?

>

To open and close files, use AssignFile and CloseFile.  Also, you'll

require the Reset and/or Rewrite functions.  Readln and Writeln can be

used to read text files with lines of 255 or less chars per line.

BlockRead and BlockWrite can be used on any file.  You'll find all this

and, of course, MUCH more, by opening the Delphi help file and searching

for "I/O routines" and "FILE I/O ROUTINES".

--

* John C. Leon, VP

* Capital Markets Technology

* Texas Commerce Bank, Houston, TX

* (a subsidiary of Chemical Banking Corp.)

* jleon@ix.netcom.com

From: gary@rix.co.nz (Gary Benner)

In article <3l2fgb$khe@newsbf02.news.aol.com>, digallery@aol.com says...

>

>I have done considerable experimentation with Delphi using most of the

>built-in components and such. I feel ready to begin developing some

simple

>applications for my own use which need to do some file I/O. But I can

not

>seem to find any reference to opening and reading and writing files! I

>have noticed the class TStream but cannot find any doc on it anywhere.

Am

>I missing something?

Try the OBJECT PASCAL LANGUAGE section in the Delphi Help. Also most of

the file I/O features of BP7 and TP7 are supported in Delphi. Note there

are some slight changes in syntax, but otherwise its all there. Good

Luck!

Gary Benner


Problem passing dates to report

#1057.FAQ	From: Arne Flemming Jensen <Arne.Flemming.Jensen@uni-c.dk>

GREGORY MCBRIDE <mcbride@gaul.csd.uwo.ca> wrote:

>

> Has anyone tried to pass a date to a report variable for reportsmith?

> I have a program that sends a number and start and end dates as report

variables

> to a ReportSmith report, but I can't get the date variables to work.

>

> --Greg

I got the same problem, until now I can send a number

but not a Datevalue. I used the example in the MAST reportexample,

but when then datevalue is to be pased reportsmith? hungs.

If only sending af number is works OK!!?????

|--------------------------------------------------------------

|  Arne Flemming Jensen

|--------------------------------------------------------------

|  Arne.Flemming.Jensen@uni-c.dk

|

|--------------------------------------------------------------

|  UNI-C Aarhus

|  Olof Palmes alle 38  Phone  : +45 86 78 44 44 - 6240

|  8200 Aarhus N        Fax    : +45 86 78 44 55

|  DENMARK

|--------------------------------------------------------------

From: Greg McBride <mcbride@gaul.csd.uwo.ca>

Arne Flemming Jensen <Arne.Flemming.Jensen@uni-c.dk> wrote:

> I got the same problem, until now I can send a number

> but not a Datevalue. I used the example in the MAST reportexample,

> but when then datevalue is to be pased reportsmith? hungs.

> If only sending af number is works OK!!?????

>

Got the answer! What I had to do was send the report variable as follows:

@DateValue=<xxxxx>

where xxxx was the date, ie. 10/12/1993 but within the angle brackets I had

to enclose the date with single quotes. So... the final thing looks

like DateString := '@DateValue=<' + chr(39) + '10/12/1993' + chr(39) + '>'

         ^             ^

         |             |

         |          Whatever your report var. is named

         |

         |

    whatever string var you'll send to the control

chr(39) I think is correct, but you may want to doublecheck.

I got this from tech support from a ReportSmith techie.


Setting Checked state on TCheckBox

#1058.FAQ	From: Chuck Jazdzewski <cjaz@borland.com>

> I've got a TCheckBox on a form that I'm using, but have strange problems

> when setting the Checked State:

>

>         this code is may not be accurate as I'm doing it from memory, but it

> will show what I'm getting at.

>

> begin

>         If CheckBox1.Checked = False Then

>                 CheckBox1.State := cbChecked

>         Else

>                 CheckBox1.State := cbUnChecked;

> end;

>

> This works if the box is unchecked at the start and I just set it to

cbChecked

> but as an If else statement fails.

>

> Whats going on?

I am not sure what is wrong since I tried the following and it worked:

  if not Checkbox1.Checked then

    CheckBox1.State := cbChecked

  else

    CheckBox1.State := cbUnChecked;

also there is a much easier way to do this in:

  CheckBox1.Checked := not CheckBox1.Checked;

Chuck Jazdzewski (cjaz@borland.com)

Delphi Development


Resize Forms

#1059.FAQ	From: Steve Teixeira <steixeir@borland.com>

bdowell@cybernetics.net wrote:

>

> Has anyone noticed a resize event handler problem under DELPHI? It appears

> that the resize event is triggered as soon a form is created.   I noticed

the problem

> when I tried to do this in the resize event of a form

>

>     Color:=clPurple;

>

> The form background was purple upon creation of the form when it should have

> turned purple only when I resized the form.  Any input and experimentation

would

> be appreciated.

>

That's acutally as-designed.  Since Windows issues a wm_Size message after a

window

is created, Delphi fires the event.

        -Steve Teixeira

         steixeir@borland.com


Delphi for OS/2, Mac

#1060.FAQ	From: Steve Teixeira <steixeir@borland.com>

qms1.life.uiuc.edu (Stewart Berlocher) wrote:

>

> In article <3ksa61$q5o@druid.borland.com>, Steve Teixeira

> <steixeir@borland.com> wrote:

>

>

> > By developing for Win95 and NT simultaneously, we get the most

> > bang for our development buck, and we are assured of having a 100% Win95-

> > compatible product.  Sometimes you have to make tough call, and this is

just

> > one of those tough calls that Borland must make right now.

> >

> >         -Steve Teixeira

> >          steixeir@borland.com

>

> I know this is futile, but is there going to be Delphi for the Mac?  I'm

> at a University where almost all teaching software is on the Mac, and the

> lack of something like Delphi or VisualBasic drives me nuts.  Just

> hoping...

Borland's announced no plans to produce a Mac version of Delphi at this time.

Sorry 'bout that.


MessageDlg & Dialogs UNIT

#1061.FAQ	From: Steve Teixeira <steixeir@borland.com>

mwj@nyc.pipeline.com (Jin Mai) wrote:

>

>

> Here is a Delphi problem which I am lookinf for

> a solution:

>

> If I add InputBox() or MessageDlg() function to

> a unit, Delphi displays invalid identifier error.

> It turns out MessageDlg() belongs to UNIT Dialogs.

> I put Dialogs in the use statement and the program

> compliles with on error. Is there any way to set Delphi

> to automatically add a unit to the use statement whenever

> progammers use a function in that unit?

>

> If not, should it be consider a new feature in next Delphi?

>

How is Delphi to know that you want the MessageDlg() function from the

DIALOGS unit rather than the one from the STEVEDLG unit or the JINDLG unit?

The burden is on the programmer to know the which unit contains the class or

functions that he or she needs.

        -Steve Teixeira

         steixeir@borland.com


Sparse unit removed in release version

#1062.FAQ	From: Steve Teixeira <steixeir@borland.com>

hallvard@falcon.no (Hallvard Vassbotn) wrote:

>

> In the beta version of Delphi (Field test #5) there was a unit named Sparse

> that implemented some useful objects for handling sparse arrays (i.e the

> class types TSparsePointerArray, TSparseList and TStringSparseList).

>

> This unit does not exist in the release version of Delphi (standard), and

> the types seems to have be moved into the implementation part of the

> Grids unit (we don't have the source code yet). This means that these

> nice objects are out of reach.

>

> Will the sparse unit be made available later or in the client/server

version?

> The objects are not mentioned in any of the documentation, but there are

> refernces to them in the delphi\doc\classes.int and delphi\lib\grids.dcu.

>

> Useful routines and objects like this should not be hidden away from us.

>

When you get the VCL source code, you'll be able to pull the TSparse...

classes

out of the implementation part of GRIDS.PAS.

        -Steve Teixeira

         steixeir@borland.com


Memory Allocaton and Freeing

#1063.FAQ	From: koterski@genghis (Steve Koterski)

Rune Moberg (mobergru@oslonett.no) wrote:

[...]

: Please, run this by me again...

: If I allocate memory to a pchar (or any pointer), say 16K, will it not

: automatically be freed when my app exits?

: ouch...

No. If you allocate memory to the same PChar twice, without freeing the

memory space between, the memory space created by the first allocation

will still exist, but without a pointer to it because the pointer has

been redefined to point to another address in memory.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


How to make DropDownCombo in StringGrid or other Grid?

#1064.FAQ	From: e5qm@jupiter.sun.csd.unb.ca (Justin MacLeod)

Fellow Delphi'ers:

How can I make a DropDownComboBox appear in the cell of a StringGrid. I

know there has to be a way to do this, since Delphi does it in the

ObjectInspector, and the IDE is WRITTEN in Delphi. I want the nice look

of a ComboBox with "no borders" so it fits nicely into the cell without a

big black border around the combo. Does anyone know how to remove the

border from the combobox, since there is no BorderStyle property?

This feature would be wanted by a lot of folks (especially in the DBGrid

I think), so anyone looking for a component to develop, go right ahead!

Borland obviously developed this for use in the Delphi IDE, but thought

that no one would want to use this feature in their apps, so did not

include it in the Visual Component Library. Wrong! If only I had a nice,

printed copy of the VCL reference....then maybe it would be easier to

develop my own custom control to do this...sigh!

--

  v=====v=====v\    0 __     | Justin MacLeod

  T\  :.  .   . \,_/_J _>_   | B.Sc(CS) Co-op IV Software Engineer

__I_`v=====v=====v__ /|______| University of New Brunswick

     T           T  | |      | Fredericton, New Brunswick, CANADA

     I           I  ^ ^      | "Behind the 8 ball again?!?!"

From: gmitchel@garnet.acns.fsu.edu

Go to the Contents Page of the Delphi Help file.  You can access the VCL

Reference there.  It is supposed to be the same as

the printed reference manual for VCL.

What is shameful is the price of VCL source code does not include the VCL

reference manual.  It is just one 3.5 in. floppy disk.

At $100, that's a 20,000% mark-up.  Geesh!  Borland has no shame!  Talk abour

rapacious!  You have to buy the supplemental

manual set to get the reference for VCL.

Yes, Steve Texeira.  I know.  You did it to save money.  Just explain to us,

please, why you mark-up a floppy disk 20,000% and

a set of manuals maybe 200%.  It makes no sense.

Mitch


Declaring APIs in Delphi

#1065.FAQ	From: rworks@itsnet.com (Steve Peterson)

bmurray@pluto.njcc.com (Brad Murray) wrote:

>Am I going crazy or is it not mentioned anywhere in the manuals how to

>declare and use Windows API functions in Delphi.  I would appreciate a

>sample of how to declare some API.  For example WriteProfileString.

All of the Windows API functions are available through the WinProcs unit.

Just

include it in any unit that needs API functions.  You might also need to

include

WinTypes to access some windows structures and constants.

BTW, you don't need to use WriteProfileString at all.  Look up the TIniFile

type

in help.  TIniFile encapsulates all of the Ini file functions, and makes them

much

easier to use.

Steve

From: keeper@netcom.com (Mark R. Johnson)

In article <3l7a9h$8b9@earth.njcc.com>,

   bmurray@pluto.njcc.com (Brad Murray) wrote:

>Am I going crazy or is it not mentioned anywhere in the manuals how to

>declare and use Windows API functions in Delphi.  I would appreciate a

>sample of how to declare some API.  For example WriteProfileString.

>

>Thanks in advance,

>       Brad

You don't need to declare Windows API functions.  Borland has done

it for you.  Just include the WinTypes and WinProcs units.  Then

use the API to your heart's delight.

For declaring non-Windows API functions look under importing DLL

functions (and related topics).

--Mark Johnson

______________________________________________________________________________

Mark R. Johnson     _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

Atlanta, GA USA    _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

keeper@netcom.com _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

From: bmurray@pluto.njcc.com (Brad Murray)

In article <3l9f67$msg@itchy.itsnet.com>,

   rworks@itsnet.com (Steve Peterson) wrote:

>bmurray@pluto.njcc.com (Brad Murray) wrote:

>>Am I going crazy or is it not mentioned anywhere in the manuals how to

>>declare and use Windows API functions in Delphi.  I would appreciate a

>>sample of how to declare some API.  For example WriteProfileString.

>

>All of the Windows API functions are available through the WinProcs unit.

>Just include it in any unit that needs API functions.  You might also need to

>include WinTypes to access some windows structures and constants.

>

>BTW, you don't need to use WriteProfileString at all.  Look up the TIniFile

>type in help.  TIniFile encapsulates all of the Ini file functions, and makes

>them much easier to use.

The TIniFile type doesn't delete items and a few other functions that I need

for INI files.  Plus I am converting a VB program that uses the APIs directly.

At the same time, I may need to access strings that are bigger than 255

characters.  Is it me or does the 255 character limit make the pascal strings

pretty useless?

Brad

_______________________________________________________________________

 Bradley S. Murray       Princeton Computer Consulting  (609) 799-5300

 bmurray@pluto.njcc.com    Princeton, NJ 08543-7345     Fax:  275-5651

From: vincer@iaccess.za (Vince Risi)

In article <3l7a9h$8b9@earth.njcc.com>,

bmurray@pluto.njcc.com (Brad Murray) wrote:

> Am I going crazy or is it not mentioned anywhere in the manuals how to

> declare and use Windows API functions in Delphi.  I would appreciate a

> sample of how to declare some API.  For example WriteProfileString.

>

> Thanks in advance,

>       Brad

> _______________________________________________________________________

>  Bradley S. Murray       Princeton Computer Consulting  (609) 799-5300

>  bmurray@pluto.njcc.com    Princeton, NJ 08543-7345     Fax:  275-5651

>

Use the inifiles unit (inifiles.dcu).

var

  winini : tinifile;

begin

  winini := tinifile.create('win.ini');

  x := winini.readstring(...);

  winini.writestring(...);

  winini.free;

end;

From: aao630@huxley.anu.edu.au (Abimbola A Olowofoyeku)

In article <D66At4.6AE@aplcenmp.apl.jhu.edu> (Tue, 28 Mar 1995 23:05:28 GMT),

Gunther Birznieks (birznie@aplcenmp.apl.jhu.edu) wrote:

: >If you include all of winprocs (use winprocs) will it take up a lot of

: >extra space like including all the WinAPI functions does in VB?

: >-- This is the usual reason that in VB, you only declare the specific

: >functions you need from the API instead of including them by default

: >in a .bas file.

Borland's "smart" linker will strip out functions that are not referenced.

--

The Chief

---------

Dr. Abimbola A. Olowofoyeku (The African Chief)

E-mail   : laa12@keele.ac.uk

Author of:

1. Chief's Installer Pro 1.70 for Windows:

   winner of PC PLUS Magazine Gold Award (April 1995 U.K. edition) **

      ftp://ftp.demon.co.uk/pub/ibmpc/windows/chief/pro/cinstp17.zip

2. Windows Command Line and Batch Processor (WCL) v7.80:

      ftp://ftp.demon.co.uk/pub/ibmpc/windows/wcl/wincmd78.zip

From: ballpe@cnb07v.hhcs.gov.au

In article <3l7a9h$8b9@earth.njcc.com>, bmurray@pluto.njcc.com (Brad Murray)

writes:

> Am I going crazy or is it not mentioned anywhere in the manuals how to

> declare and use Windows API functions in Delphi.  I would appreciate a

> sample of how to declare some API.  For example WriteProfileString.

>

> Thanks in advance,

>       Brad

> _______________________________________________________________________

>  Bradley S. Murray       Princeton Computer Consulting  (609) 799-5300

>  bmurray@pluto.njcc.com    Princeton, NJ 08543-7345     Fax:  275-5651

>

Brad,

Don't know about the manuals, but here's the entry from the Windows API Help

file:

WriteProfileString (2.x)     (WINPROCS unit)

function WriteProfileString(ApplicationName, KeyName, Str: PChar): Bool;

The WriteProfileString function copies a string into the specified section of

the Windows initialization file, WIN.INI.

Parameter       Description

ApplicationName Points to a null-terminated string that specifies the section

to which the string is to be copied. If the section does not exist, it

is created. The name of the section is case-independent; the string may be any

combination of uppercase and lowercase

letters.

KeyName Points to the null-terminated string containing the entry to be

associated with the string. If the entry does not exist in the

specified section, it is created. If this parameter is NIL, the entire

section,

including all entries within the section, is deleted.

Str     Points to the null-terminated string to be written to the file. If

this

parameter is NIL, the entry specified by the KeyName

parameter is deleted.

Returns

Returns nonzero if the function is successful. Otherwise, it is zero.

Comments

Windows keeps a cached version of WIN.INI to improve performance. If all three

parameters are NULL, Windows flushes the cache.

Sections in the WIN.INI initialization file have the following form:

[section]

entry=string

    .

    .

    .

See Also

GetProfileString

WritePrivateProfileString

Kernel functions (3.1)

Hope this helps you find the functions you want.

--

Peter Ball (ballpe@cnb07v.hhcs.gov.au)  "These views are mine alone"

Systems Development Officer, Department of Human Services and Health,

Brisbane, Queensland, Australia. Telephone : (07) 360 2637

Post : Information Services Section, GPO Box 9848, Brisbane QLD 4001,

AUSTRALIA


How do I forfeit control?

#1066.FAQ	From: bstowers@cybernetics.net (Brad Stowers)

kriutort@vt.edu (Kevin Riutort) wrote:

> How do I allow a user to gain control of my application while it's in a

> loop (a graphics animation for example).

Exactly what kind of control do you want to give the user?  Allow them to

cancel the process?

I'm not sure, but I think what you are looking for is

Application.ProcessMessages.  If you put that statement in your loop, it

will allow processing of messages, which prevents your loop from hogging

the system and not allowing other processes to execute (becuase messages

weren't being processed).

Regards,

Brad

--------------------------------------------------------

Brad Stowers             |  bstowers@cybernetics.net

deltaComm Development    |  My views are my own...

Telix for Windows & DOS  |  Keep yer hands off of 'em.

--------------------------------------------------------

      http://www.cybernetics.net/users/bstowers/

From: Steve Teixeira <steixeir@borland.com>

Subject: Re: Delphi: Newbie: How do I forfeit control?

Date: 28 Mar 1995 16:02:16 GMT

kriutort@vt.edu (Kevin Riutort) wrote:

>

> Hello Programmers:

>

> I have a question which should be fairly obvious, but I'm having trouble:

>

> How do I allow a user to gain control of my application while it's in a

> loop (a graphics animation for example).

> (yes, I did r.t.f.m. but I don't have a language ref. yet and I've been

> hypertexting the on-line ref. so long I want to puke)

>

> A code fragment or an explanation of the appropriate function/procedure

calls

> would be _greatly_ appreciated.

>

Call Application.ProcessMessages in your loop.

        -Steve Teixeira

         steixeir@borland.com

--

Allan


Dates and times in a messagebox

#1067.FAQ	From: koterski@genghis (Steve Koterski)

Derek Stutsman (iw84@jove.acs.unt.edu) wrote:

: I am having problems with (what should be) an easy task.

: I want to throw up a message box that says something to the effect of

"Process began at {Time} on {Date}."

: I have tried using Datetostr, Datetimetostr, etc but for whatever reason my

syntax is apparantly bad.

: Code follows:

: dummy := Application.MessageBox('Process started on

'+DateTimetostr(date)+'at'+Datetimetostr(time)+'.','Survey START', mb_OK);

: This gives me a Type Mismatch error, and I have tried altering it in several

ways.  Any suggestions?

The MessageBox method of TApplication, like the API function of the same

name, requires the first two parameters (the text and the message box

caption) be of type PChar, not a String as you are using it. You would

either need to store these two bits of information to two PChar variables

or use the MessageDlg function. The MessageDlg function does essentially

the same thing, but does not allow you to specify the dialog's caption.

Here's an example that may help you to use the MessageBox method:

   procedure TForm1.Whatever;

   var

     DlgText, DlgCaption: array [0..255] of Char;

     TextText, TextCaption: String;

   begin

     TextText := 'Process started on ' + DateTimeToStr(Date) + ' at ' +

       DateTimeToStr(Time) + '.';

     TextCaption := 'Survey START';

     StrPCopy(DlgText, TextText);

     StrPCopy(DlgCaption, TextCaption);

     Application.MessageBox(DlgText, DlgCaption, mb_OK);

   end;

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


"SelText: string;

#1068.FAQ	From: steve.wiser@richcon.com (Steve Wiser)

On 03-21-1995, ZOO KEEPER wrote to ALL about Delphi: "SelText:

string;.

ZK> From: keeper@netcom.com (Zoo Keeper)

ZK>

ZK> Over an over again I keep running into Delphi's strings, and they just

ZK> don't mix well with Windows.  When the String type first appeared in

ZK> Turbo Pascal, it was great.  Being an array, you could quickly and

ZK> easily access the individual characters within.  Using the 0th

ZK> character to hold the length was a stroke of genius, and very useful

ZK> at the time.

Hello Zoo Keeper:

I don't know if you have access to the magazine Windows Tech (Mar 95)

but if you do there is a great article in it about Pascal data

types(strings being  one of course) .   What this article suggest and

demonstrates is how to  "create a record class that encapsulates

Pascal's data types and modifies string grids and data entry forms so

that they can accommodate any record."  This is to keep you from

"manually translating each type to and from the  native data format to

whatever format the corresponding controls use."

The article represents the development of a "dynamic record types."

I am not yet verse in all the programming issues of Pascal and Delphi

but this seems on the surface exactly what you may be talking about.

Hope this helps.

Steve

---

 * KWQ/2 1.2i * This tagline stolen by KWQ Mail/2.


Frequently Asked Questions - Pointers and Components
Pointers and Components

#1069.FAQ	From: Jerry Black <black@xmission.com>

vdata@inforamp.net (Bryan Zarnett) wrote:

>

> Im trying to place the data from a TEdit component into a string pointer.

> Someone say this is simple...

>

> basically I wrote

>

> var

>  data: ^string;

>

> Form1.TEdit1_Exit(Sender:TObject)

> begin

>      data^:=TEdit1.Text;

> end;

>

Try this:

TYPE

        MYDATA = ^STRING;

VAR

        data : MYDATA;

Form1.TEdit1_Exit(Sender:TObject)

begin

        data^ := TEdit1.Text;

end;

Hope this is of some help.

Jerry Black

From: dmurdoch@mast.queensu.ca (Duncan Murdoch)

In article <3ldnjv$9vn@news.xmission.com> Jerry Black <black@xmission.com>

writes:

>TYPE

>        MYDATA = ^STRING;

>VAR

>        data : MYDATA;

>Form1.TEdit1_Exit(Sender:TObject)

>begin

>        data^ := TEdit1.Text;

>end;

This has the same problem as the original:  you never allocated data^.  You

need

  data := NewStr(TEdit1.Text);

The NewStr function allocates space for the string on the heap, and returns a

pointer to it.  One warning:  In BP, NewStr returns Nil if the string is

empty.  This means that something like Writeln(data^) will write garbage, or

cause a GPF.   I don't know if Delphi fixes this, but if not, you should write

a little wrapper routine that checks for Nil, so something

like StringFromHeap(data) will always return a valid string.

It's also possible to use just

  New(Data);

  Data^ := TEdit1.Text;

but this version wastes heap space.  It always allocates 256 bytes, regardless

of the length of the string.  NewStr just allocates the minimal amount of

space.

If you use NewStr, use DisposeStr to get rid of it; use Dispose with New.

Duncan Murdoch

From: pete@miller.cs.uwm.edu (Peter J Ikusz)

In article <3lckv4$q9m@usenetw1.news.prodigy.com>,

Pete Royston <DBRK81A@prodigy.com> wrote:

>just defines a pointer, it does not allocate space for it.  The

>assignment appears correct.  The GPF comes from the "data" pointer not

>being initialized.

>--Pete

I think he is trying to so something similar to:

        char *str;

        str = struct.pointer_to_str_member;

in C.

Is there a way to do this in Pascal?

I guess, knowing what I do about C, would have expected this behavior as well.

That, and not having used Pascal in 10 years.

Thanks,

-Pete

From: bstowers@cybernetics.net (Brad Stowers)

vdata@inforamp.net (Bryan Zarnett) wrote:

> Im trying to place the data from a TEdit component into a string pointer.

> Someone say this is simple...

>

> basically I wrote

> var

>  data: ^string;

> Form1.TEdit1_Exit(Sender:TObject)

> begin

>      data^:=TEdit1.Text;

> end;

> Got a GPF...any ideas how to do this right?

By now you've seen the right way to do it (allocate space for the pointer

with StrNew(TEdit1.Text), but I thought someone should mention that when

you allocate space to a pointer, you must remember to free it as well with

StrDispose when you are done with it.

Regards,

Brad

--------------------------------------------------------

Brad Stowers             |  bstowers@cybernetics.net

deltaComm Development    |  My views are my own...

Telix for Windows & DOS  |  Keep yer hands off of 'em.

--------------------------------------------------------

      http://www.cybernetics.net/users/bstowers/

From: stow@skyfox.usask.ca

In a previous article, dmurdoch@mast.queensu.ca (Duncan Murdoch) wrote:

>The NewStr function allocates space for the string on the heap, and returns a

>pointer to it.  One warning:  In BP, NewStr returns Nil if the string is

>empty.  This means that something like Writeln(data^) will write garbage, or

>cause a GPF.   I don't know if Delphi fixes this, but if not, you should

write

>a little wrapper routine that checks for Nil, so something

>like StringFromHeap(data) will always return a valid string.

The RTL for BP 7.0/7.01 came with source code for the "Objects" unit, which

lets you edit NewStr to fix this bug.

The original is something like:

function NewStr(const S: string);

var P: PString;

begin

   If S = '' then P := nil

   else begin

           GetMem(P,Length(S) + 1);

           P^ := S;

        end;

   NewStr := P;

end;

Just reduce it to the two lines in the "else" condition and it works like a

charm.  Side benefit of speeding things up noticeably when you have

to make large trees or linked lists of strings on a slow computer because the

"If S = ''" condition no longer has to be tested every time a NewStr is

called.

If Delphi still has this "bug", doesn't Delphi come with source code

so you can fix it's NewStr function?


A Winexec question

#1070.FAQ	From: bstowers@cybernetics.net (Brad Stowers)

tommyt@studserv.hedmarkdh.no (Tommy Thoresen) wrote:

> In my program i want to start an other programs with input from the user

> which i save in a STRING variable called command.

> As the old pascal function exec() is away i tried to use the API function

> called winexec().

> The problem is that the function not like winexec(command,??_MAXIMIZE).

WinExec expects a type of ARRAY OF CHAR, or a pointer to the same.  You are

passing a STRING type.  SysUtils provides to functions, StrPas and StrPCopy

to convert to and from these types.  Try this:

var

  Buff: array[0..255] of char;

begin

  WinExec(StrPCopy(Buff, Command), SW_SHOWMAXIMIZED);

end;

> However it will work if it was written like this

> winexec('program',??_MAXIMIZE). Why is it so?

> command is a string, and 'program' is also a string.

The compiler automagically converts any hardcoded strings to the type

(array of char or string) that is required by the procedure/function call.

Regards,

Brad

--------------------------------------------------------

Brad Stowers             |  bstowers@cybernetics.net

deltaComm Development    |  My views are my own...

Telix for Windows & DOS  |  Keep yer hands off of 'em.

--------------------------------------------------------

      http://www.cybernetics.net/users/bstowers/

From: jnhodges@nps.navy.mil (John N. Hodges)

In article 502@studserv.osir.hihm.no, tommyt@studserv.hedmarkdh.no (Tommy

Thoresen) writes:

>In my program i want to start an other programs with input from the user

>which i save in a STRING variable called command.

>

>As the old pascal function exec() is away i tried to use the API function

>called winexec().

>

>The problem is that the function not like winexec(command,??_MAXIMIZE).

>However it will work if it was written like this

>winexec('program',??_MAXIMIZE). Why is it so?

>

>command is a string, and 'program' is also a string.

Tommy,

Another avenue is to look up the ExecuteProgram() function in

\DELPHI\DEMOS\DOCS\FILMANEX\FMXUTILS.PAS.

There  are some other nice functions in there as well.

---

*   LT Nick Hodges, USN                     Naval Postgraduate School

*

*   jnhodges@nps.navy.mil                Information Technology Management

*

*   CIS: 71563,2250 AOL: NHodges                   Monterey, CA

*

*   The opinions expressed above are entirely my own and not the Navy's.

*

*   Visit my homepage:  http://vislab-www.nps.navy.mil/~jnhodges

*


How to use tabs in TListBox strings?

#1071.FAQ	From: A.Blumsohn@Sheffield.ac.uk (Aubrey Blumsohn)

In article <3lbvub$489@canopus.cc.umanitoba.ca>, waletz@eeserv.ee.umanitoba.ca

(James Waletzky) says:

>I have a list box that displays strings with each string actually

>being made up of two substrings which I would like to be separated

>by a tab character. This would, in effect, give two columns in my

>list box. How can I setup the list box to interpret the tab (#9)

>character?

You will probably find that customizing TStringGrid control

will provide a better solution to your problem.

Aubrey Blumsohn

From: bstowers@cybernetics.net (Brad Stowers)

waletz@eeserv.ee.umanitoba.ca (James Waletzky) wrote:

> Perhaps someone can help me out with this (seemingly) simple problem.

> I have a list box that displays strings with each string actually

> being made up of two substrings which I would like to be separated

> by a tab character. This would, in effect, give two columns in my

> list box. How can I setup the list box to interpret the tab (#9)

> character?

> Before I add the whole string to the list, I do:

>       string1 + #9 + string2

> and then add the result to the list box. However, the tab is not

> interpretted and all I get in the list is a square. I know the Windows

> API has a list box style of LBS_USETABSTOPS, but I can't find the

> equivalent in Delphi.

Delphi does not provide a direct method to set the LBS_USETABSTOPS style.

You need to override the TListBox.CreateParams in a descendant object and

do this:

  Params.Style := Params.Style or LBS_USETABSTOPS;

Regards,

Brad

--------------------------------------------------------

Brad Stowers             |  bstowers@cybernetics.net

deltaComm Development    |  My views are my own...

Telix for Windows & DOS  |  Keep yer hands off of 'em.

--------------------------------------------------------

      http://www.cybernetics.net/users/bstowers/

From: ferincz@chemie.fu-berlin.de (Jozsef Ferincz)

waletz@eeserv.ee.umanitoba.ca (James Waletzky) writes:

[snip]

You could also try to use TStringGrid, you can "disign" the

columns you need.

Best regards, Jozsef

--

Jozsef Ferincz                     E-mail: ferincz@chemie.fu-berlin.de

Freie Universitaet Berlin

Institut fuer Organische Chemie       Tel:   +49.30.838-2677, 838-5363

Takustr. 3, D-14195 Berlin, Germany   Fax:   +49.30.838-5163, 838-4248


Some General Questions

#1072.FAQ	From: Marc@landscap.demon.co.uk (Marc Palmer)

In article: <3le1beE9cg@uni-erlangen.de>  gedeck@pctc.chemie.uni-erlangen.de

(Peter Gedeck)

writes:

>

> Hi,

>

> Two days ago I received my copy of Delphi and since then I have

> played around with it a bit. There are several things I found:

>

> 1.) TIntegerEdit

>   Did anyone already wrote something like this and would like

>   to share his experience? I already this, but had the following

>   problem. I created a descendant of TEdit and added a property

>   called Value (type integer). This property calls two methods

>   SetValue and GetValue. The GetValue function traps the

>   conversion-error that is created if the Text-field is not a

>   number and creates a warning. Then I installed this new component

>   and inserted in a Form. After installing the Text-property is

>   "TIntegerEdit", obviously no number and consequently a conversion-

>   error is created. So, how can I force a different entry in Text,

>   that will not be changed, when changing the Name of the component?

Why didn't you use the mask edit component? Yeah, you have to call

IntToStr and StrToInt to set/get the Text property, but it saves

making another component!

> 2.) About-Dialog

>   If I create a new Form to display something that is not really

>   needed all the time, Delphi put its creation in the Project-source

>   code. Is this really sensible or isn't it better to create this

>   Form when needed and then destroy it after it was used ?

>   I tried the second way and found, that not all memory is released

>   after destroying. Is this something I have to worry about or is

>   this something that is normal ?

Are you freeing the form after it's been closed? You should do this:

procedure TForm1.BtnClick(Sender : TObject);

var

  Form : TForm2;

begin

  Form := TForm2.Create(Self);

  try

    Form.ShowModal;

  finally

    Form.Free;

  end;

end;

> 3.) WMF-Files

dunno

> 4.) Print a file from Delphi (Bug ?)

>   I tried to print a file (ole2win.pas) from the editor using the

>   File|Print command selected Header lines on and pressed ok. After

>   several seconds the following error message is displayed:

>   S3FLAT.DRV General protection fault at 0001:5a0c

>   If I print the file without Header lines everything works fine,

>   except that it takes a relly long time to print only 4 to 5 pages.

>

>   Additional information:

>   German version of Delphi, HP Laserjet 4L with the print manager

>   provided by HP (quite a new version)

We have same printer (U.K. though) and I print out loads of stuff fine.

> 5.) Minimizing a MDIChild-Form in edit mode (Bug ?)

>   Just try to minimize a newly created MDIChild-Form (at the Delphi

>   level, not while running a MDI application). This results in

>   a general protection fault in Modul COMPLIB.DCL at 0019:4ec7

There is a bug relating to MDI minimuzing - this may be it.

> 6.) TMemo Component (Bug ?)

>   If I insert a TMemo component in a Form, the Text property is not

>   displayed in the Object inspector. The Object browser marks it as

>   published. This is in the german version.

>   Any comments on this - same experience, especially from germans ?

Tmemo doesn't use the Text property. It uses the Lines property (a

TStrings array). Use Lines.Add('line to add') to edit it.

> 7.) Creating Graphs

>   Which Object should I use as a base for a new component, like

>   TChartFX that means something to plot graphs and functions?

>   There are so many different Objects in Delphi, that it gets really

>   confusing.

TGraphicControl is probably as close as you'll get. ChartFx is a VBX

that doesn't use any delphi components AFAIK.

********************************************************************

* Marc P.                               E-Mail me for PGP 2.6 key  *

*                                                                  *

* "Most of the ideas I have at the moment have to do with things   *

* that are completely impossible, so I am wary about sharing them. *

* They are, however, the only thoughts I have." - Dirk Gently      *

********************************************************************

From: rudyj@ic.net

Subject: Re: Delphi bug?

Date: 31 Mar 1995 01:38:40 GMT

In <3lenl7$8pc@news.panix.com>, anatoly@panix.com (Anatoly Goroshnik) writes:

>When I try to do the following I get GPF (code is taken from Delphi help):

>

>procedure TForm1.Button1Click(Sender: TObject);

>var

>  Contents: TStringList;

>begin

>  try

>     Contents.LoadFromFile('LIST.TXT');

>  finally

>     Contents.Free;

>  end;

>end;

>

>Am I doing something wrong?

>

>Anatoly Goroshnik   |   anatoly@panix.com

>ISC Inc.

Insert the following before you use your TStringList.

Contents := TStringList.Create;

Hope this helps.

-----------------------------------------------------------------------

Jeff Bogatay

rudyj@ic.net

74654,3321


TStringList in Delphi

#1073.FAQ	From: bstowers@cybernetics.net (Brad Stowers)

cwhite@teleport.com (Curtis White) wrote:

> This might be a stupid question but I am trying to define a

> TStringList in Delphi and it keeps crashing with a GPF.  I define the

> type and the var in the interface section.  I do this because I want

> to access these values from within another unit that uses this unit.

> Then in my event handler I try to add values to the list, using the

> Values method.  I am doing this to hold the info from/for an ini file.

> I tried using the form:

> variable.Values['inifileitem'] := 'The Value';

> Then when I run the program, I get a GPF in some other VCL module.

> How do I set up and use a TStringList object?  Apparently I am doing

> something wrong.

Declaring a variable of type TStringList really only declares a pointer.

You need to initialize the variable in the unit's startup code with:

initialization { can substitute BEGIN here, but help recommends not to }

  MyVar := TStringList.Create;

end. { of unit }

This brings up a second problem.  When you create an object like this

yourself, you are responsible for cleaning it up.  Since you say this

object is a global variable provided by a unit, you may not technically

need to clean it up, but it is an EXTREMELY bad habit to get into.  If, for

instance the variable were a bitmap handle, and you ended your program

without freeing it, it would result in lost system resources.  To free a

global variable provided by a unit, you'll need to "hook" your unit into

the exit chain.  Here's how you do that:

var

  Chain: pointer;

procedure MyExitProc; far;

begin

  { Restore the address of the old exit procedure }

  { so that when this is finished, it continues on   }

  ExitProc := Chain;

  { Do all of your shutdown code }

  MyVar.Free;

end;

initialization

  { Save the address of the old exit procedure }

  Chain := ExitProc;

  MyVar := TStringList.Create;

end. { of unit }

Hope that helps.

Regards,

Brad

--------------------------------------------------------

Brad Stowers             |  bstowers@cybernetics.net

deltaComm Development    |  My views are my own...

Telix for Windows & DOS  |  Keep yer hands off of 'em.

--------------------------------------------------------

      http://www.cybernetics.net/users/bstowers/

From: cityzoo@mindspring.com (CITY ZOO, Inc.)

In article <3lhbri$q01@news0.cybernetics.net>,

   bstowers@cybernetics.net (Brad Stowers) wrote:

>initialization

>  { Save the address of the old exit procedure }

>  Chain := ExitProc;

>  MyVar := TStringList.Create;

>end. { of unit }

>

>Hope that helps.

>

>Regards,

>Brad

Do you not also need a "ExitProc := MyExitProc;" after the

"MyVar := TStringList.Create;"?  (You probably wouldn't

want to put it in front of the "MyVar := ..." since it

hasn't been allocated by that point...)

--Mark Johnson

____________________________________________________________________________

Mark R. Johnson   _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

Atlanta, GA USA   _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

keeper@netcom.com _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


Displaying messages via panel

#1074.FAQ	From: koterski@genghis (Steve Koterski)

Ron Hula (nrgmaker@delphi.com) wrote:

:

: I'm trying to display a status message using a panel to show

: the progress in updating a database.  The panel's caption doesn't get

: updated until the end of the database loop (yes the panel.caption:= is

: in the loop).

:

: Is there an even timer or something I need to set to get the panel update

: to catch up with the database update?

You might want to take a look at the ProcessMessages method. Some Windows

messages may have a lower priority than others (screen updates versus

iterating through a table) and thus get relegated to the message queue

until a quieter moment, at which time they are given a time slice and

processed. The ProcessMessages method interrupts the application and

forces the processing of queued messages.

Remember, however, that this will not discriminate between queued meessages

of Delphi origin and those generated from other sources. The use of this

method may degrade performance of the application using it to a greater or

lesser degree, depending on the amount of messages in the queue. Try it,

see if it falls in a range acceptable to your needs.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

From: whimmel@jax.jaxnet.com (William Himmelstoss)

Ron Hula (nrgmaker@delphi.com) wrote:

:

: I'm trying to display a status message using a panel to show

: the progress in updating a database.  The panel's caption doesn't get

: updated until the end of the database loop (yes the panel.caption:= is

: in the loop).

:

: Is there an even timer or something I need to set to get the panel update

: to catch up with the database update?

:

        I'm not sure if there's a better way, but what I do is call

        Application.ProcessMessages while in the loop.

        Be sure and disable the controls the user shouldn't have

        access to while your program is processing or it could make

        some nasty (reentrancy?) problems.

--

        Originally: Bill Himmelstoss

        Virtually: whimmel@jaxnet.com

        Physically: Dragon's Domain +1 904 268-9203 (V.FC)

        Slowly: 1:112/57@fidonet.org

        Webly: <A HREF="http://jax.jaxnet.com/~whimmel">My Homepage</A>

        Electroencephalographically: TBD


Delphi Documentation Errata

#1075.FAQ	From: sterkenb@stevin (Sterkenburg)

Marc Palmer (Marc@landscap.demon.co.uk) wrote:

: I haven't seen anyone else point out these documentation mistakes :

: 1) The TFont.Height and TFont.Size properties' documentation mentions

:    using the Height property as the *pixel* height of the font. This

:    is *wrong*. Here is what the help file entry for it says:

:    "The Height property is the height of the font in pixels. It is the

:     size of the font plus the font's internal leading. If you are

:     concerned with the size of the font on the screen--the number of

:     pixels the font needs--use the Height property. If you want to

:     specify a font 's size using points, use the Size property

:     instead.Delphi calculates Height using this formula:

:     Font.Height = -Font.Size * Font.PixelsPerInch / 72

:     Therefore, whenever you enter a point size in the Height property,

:     you'll notice the Size property changes to a negative value.

:     Conversely, if you enter a positive Size value, the Height property

:     value changes to a negative value."

:    The TFont.Size help topic is also incorrect. They seem to be the

:    wrong way around. If you look at a TFont's Height property you will

:    see that *it* is negative (ie. the size in the Windows LOGFONT structure,

:    and not TFont.Size. TFont.Size represents the _Point_Size_ of the

:    font.

:    If you want to calculate the height, in pixels, of the font, use :

:

:    PixelHeight := Trunc(-Font.Height * Font.PixelsPerInch / 72);

: 2) Adding fields to a TTable ar run-time. There is a parameter missing

:    in the declaration of TFieldDefs.Add in the help file. The help file

:    shows the parameters as:

:

:      TFieldDefs.Add( const string, TFieldType, Word);

:    If you try to use this (or the Example code in the help file) it

:    will not compile, giving you the error: "," Expected.

:    I looked in the Object Browser and found that there is an extra

:    Boolean parameter at the end of the list. So the declarations is:

:      TFieldDefs.Add( const string, TFieldType, Word, Boolean);

:    The problem is that I don't know what the Boolean is for!

:    could a Borland 'dude' enlighten us? It *seems* to specify

:    whether the field is 'required' or not - at least that's what

:    DBD says when I look at the info structure.

: Anyone else spotted other mistakes?

: I think it would be a good idea to add a Doc Errata section to the

: proposed Delphi WWW Magazine. I've lost the e-mail address of the guy

: administrating that - does anyone know it? I'll mail this to him if I

: find out where he is.

: *********************************************************************

: ** Marc P.                               E-Mail me for PGP 2.6 key **

: *********************************************************************

--

==========================================================

ir. R.P. Sterkenburg               sterkenburg@pml.tno.nl

TNO Prins Maurits Lab.             Tel: +31 15 843413

Postbus 45  2280 AA  Rijswijk      Fax: +31 15 843991

==========================================================

From: rschwarz@edcen.ehhs.cmich.edu (Ron Schwarz)

In a previous article, Marc@landscap.demon.co.uk (Marc Palmer) says:

[...]

>Anyone else spotted other mistakes?

Yup -- the help file has the wrong number of parameters for the

roundrec entry -- I suspect they merely copied the info for rectangle.

They didn't include the last two items which pertain to the rounding

of the corners.

--

    "...last minute maneuvers in congress can make a mockery of

    presidential decrees."  ..Dan Rather, CBS Evening News, 3-3-95


Help with Case statement in Object Pascal

#1076.FAQ	From: jon@armory.com (Jon Shemitz)

Duncan Murdoch said

> You have to do it with if .. then ... else.  The usual convention to do

> what you want is just to format the code as follows:

>

>   lfun := lowercase(fun);

>   if        lfun = 'deg' then

>      N := ....

>   else if lfun = 'rad' then

>      N := ...

>   else if lfun = 'exp' then

>

> and so on.  Note that this is parsed as one big statement; you don't

> need semicolon separators after the N := lines.

Duncan is amazingly willing to answer these sorts of questions, and his

answers are usually accurate.  I'd just like to add a cavil and a

hairball:

The cavil -

Many people DO format nested if's that way.  However, I think they're

clearer like:

  if FirstTest

    then {...}

    else if SecondTest

      then {...}

      else {...} ;

That is, the then clause and the else clause are lined up, as the two

alternative actions selected by the one test.

The hairball -

In the specific case John Michael Okeefe cites (doing a case statement

on a <= 4 character string) you *can* cast the string to a LongInt and

do a case selection on the resulting values.  Of course, this sacrifices

clarity for efficiency, and so is probably not a very good idea.

--

http://www.armory.com/~jon                      Personal and Technical Pages

http://www.armory.com/~jon/hs/HomeSchool.html   Home School Resource Pages


How to display an array of strings?

#1077.FAQ	From: jon@armory.com (Jon Shemitz)

In article <kuusama.796659057@sci.fi>,

Juha Kuusama <Juha.Kuusama@samplerate.fi> wrote:

>So, I need a memory examiner/editor for a DSP board connected to a PC.

>Getting data in and out to the DSP board should be no problem, once I

>found where i/o port access is documented(?). But what component is best

>suited to display the data? (I suspect that the answer is one of your

>own, but I'm not up to that yet.) The string grid sounds like an obvious

>choice, but:

Try the Port[] and PortW[] pseudo-arrays.

>-I want the display window to be resizable, i.e. have the same kind of

>border like a form. How can I do that?

Put the string grid ON a form, and set its Align property to alClient.  Then,

when the user resizes the form, the grid resizes with it.

>-I need to access the displayed data (and size the window) by characters.

>I know how to make the font user selectable and how to limit the choice

>to fixed-pitch only, but how can I find the character size in pixels

>then? (I'm not sure I am interested about pixels; I'd rather have

>something at a character level. Like: the user changes the window size or

>display format; I then calculate that I have x by y characters, address

>is this wide, decimal number takes this many characters so the rows

>should be that many characters wide, so I get n rows etc...

A font's Height property is its pixel size, basically; its Size property is

its point size.

--

http://www.armory.com/~jon                      Personal and Technical Pages


How to include a "crystal report" in a Dephi app

#1078.FAQ	From: koterski@genghis (Steve Koterski)

Joseph P DeCello III (decello@cpp.msu.edu) wrote:

: I need to get some apps from dBASE V to Dephi up quick.  The interface

: was a peice of cake, but I'd rather not learn reportsmith just yet.

: I have crystal report that does the job for now, how can I include it

: in my Delphi app.  This report has code in it too, will it work?

: Please reply via email. I'm not caught up with this newsgroup yet,

: and by the time I am, I'll be in comp.lang.pascal.delphi (hopefully).

If you have the full version of Crystal Reports for Windows (which is

not what comes with dBASE), you can call the Crystal Print Engine as a

DLL. The documentation that comes with the full version of Crystal

describes this process and a summary of the functions that comprise the

Crystal Print Engine.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


TMemo and TEdit

#1079.FAQ	From: koterski@genghis (Steve Koterski)

ShdwMstr (drglance@mindspring.com) wrote:

[...]

: Another thing, why in the editbox you have a text field to take out Edit1

and

: in the Memobox, you do not.  If you want to put more than one memo box out

: the, it displays in runtime, memo1 and memo2.

In a TEdit component, the Text property contains the current value. In a

TMemo component, the equivalent is the Lines property. The former is a

decendent of TCaption and the latter of TStrings.

: Again, in the edit box, you can take the borders off and it does not display

: the outline, in the memo, you put border to none and you still get a border.

In addition to setting the Border property of the TEdit to bsNone, try

setting the Ctl3D property to False. This should give the effect you

intended.

[...]

: If anyone knows how to get rid of the memo1 field,...

Enter into the TMemo component's Lines property and press Ctrl-Y.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


Creating components at RUN TIME?

#1080.FAQ	From: koterski@genghis (Steve Koterski)

Anders Ohlsson (ao@spirou.e.kth.se) wrote:

[...]

: I need to create components at run time. I thought that the following

: would work:

:       MyPanel := TPanel.Create(Form1);

:       MyPanel.Left := ...

:       MyPanel.Top := ...

:       MyPanel.Width := ...

:       MyPanel.Height := ...

:       ...

:       MyImage := TImage(MyPanel);

:       MyImage.Align := alClient;

: (the code creates a panel owned by the form, and an image owned by

:  the newly created panel)

: This doesn't works just fine, except for one thing... It doesn't show

: up on the form...

The missing step you need is to explicitly set the Parent property of

the newly created object. For the TPanel component, the additional line

would be:

   MyPanel.Parent := Form1;

The TPanel will then show.

[...]

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


Crt & Form Problem.

#1081.FAQ	From: awax@dep071.ennet.krasnoyarsk.su

In article <1995Mar29.100332.1795@biivax.dp.beckman.com>,

deflenniken@biivax.dp.beckman.com writes:

>While trying to convert some DOS TP7 code to Delphi I ran across this

>problem.  It seems than there is a conflict in a Delphi program that

>mixes Crt windows and Forms. The simple case below demonstrates this.

>

>I had converted a DOS character application to run under Delphi. It

>ran fine as a crt application.  When I add a form to the program,

>and try to do a simple readln() (or any other DOS style keyboard reads),

>I get a beep from the system, and the application is hung.

>

>Any ideas?

>

>The following code illustrates the problem.

>

>

>program Testzz;

>

>uses

>  Forms,

>  Testz in 'TESTZ.PAS' {Form1};

>

>{$R *.RES}

>

>begin

>  Application.CreateForm(TForm1, Form1);

>  Application.Run;

>end.

>

>unit Testz;

>

>interface

>

>uses

>  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,

>  Forms, Dialogs, StdCtrls, WinCrt;

>

>type

>  TForm1 = class(TForm)

>    Button1: TButton;

>    procedure Button1Click(Sender: TObject);

>  private

>    { Private declarations }

>  public

>    { Public declarations }

>  end;

>

>var

>  Form1: TForm1;

>

>implementation

>

>{$R *.DFM}  { Default form with one button }

>

>procedure RunTest;

>var st : string;

>

>begin

>  writeln('Enter a string: ');

>

>  readln(st);      {Get a beep here !!}

>  writeln(st);

>end;

>

>procedure TForm1.Button1Click(Sender: TObject);

>begin

>  RunTest;

>end;

>

>end.

   Dear Sir !

   You SHOULD NOT use console-style i/o in windowed applications ! In other

words, you

should perform standard windows-style keyboard handling instead of TP-style

(such as

readln from StdIn and so on). Please refer to Windows API Reference (by

Borland) on

details of keyboard handling. You can mail to me if any.

   AWAX.


Sets

#1082.FAQ	From: awax@dep071.ennet.krasnoyarsk.su

In article <50329044412$71C7@lasernet.com>, Daryl Stogner

<dstogner@lasernet.com> writes:

>I've been trying to figure out how to read keyboard input into two

>separate SETS OF Char, for example;

>

>INPUT: WEEKS PARKS

>(Two words input on the same line separated by a space)

>

>I can get the two words easily into two separate strings like this...

>

>  SpacePos := Pos(' ',Words);

>  Word1 := Copy(Words,1,SpacePos-1);

>  Word2 := Copy(Words,SpacePos+1,6);

>

>But I need the words in S1 and S2 which are SET OF Char.  This is

>probably pretty elementary, but I don't find any examples of doing this

>in any books I have.  I want them in SETS OF type so I can compare their

>contents between each other.  What members are common, what members

>are not common and what members are contained in both words.

>

>Can someone point me in the right direction on this?

>

   Dear Sir !

   As far as I catch, you need compare two SET OF ... structures. It can be

made by

subtraction one from another. Pascal allow you subtract sets, so the

difference is a set

of the same type.

   AWAX.


Visual Solutions

#1083.FAQ	From: steve.wiser@richcon.com (Steve Wiser)

WN> From: wneimeij@vmprofs.estec.esa.nl (Wim Neimeijer)

WN> Can anyone tell me what this Visual Solutions Pack is.

WN> Borland itself doesn't have any product information available.

WN>

WN> Thanks for any replies.

This package is a selection of third party developed VBX's

with crippleware like characteristics.  Much in the package

is restricted compared with the full blown vbxs that can be

purchased from the vender.

But considering this having these

crippleware vbxs allows you to develop the application

framework to see if it works for you then you get the

full version as needed.

They are a little more than demo versions that Borland is

selling for 99$.

Additionally, no controls that are data-aware work with

Delphi since Delphi only is compatible with version 1.0 and

the  data-aware portions of the vbx are 1.0+.

The manual that comes with the components is similar to a

language reference manual excepting that you will not find a

single line of example code in it.  All methods, etc. are

explained on a outline basis, without context, example:

form1.method(value,int;value,string) type of manner. Much

like the help system for the ChartFX component supplied with

Delphi.

There seems to be some bugs in some of the components as they

are shipped.  Comm program is really crippled, xmodem only

and a poor implementation of that(single character flow, not

1024 stings as I understand it).

All references to the components seem to refer to the full

blown version since they continue to refer to data-aware

methods,etc that just are not available in Delphi.

If you want to spend your money go ahead and purchase some

vendors full package of controls.  You'll have to pay as

little as twice as much but you would have complete access to

their functionality of course except for datasoure methods.

Of course you can get the TP 7.0 parts and develop your own

Delphi objects around those that will work as components

also. Many of these parts are available at many locations

across the country in SWAG files and on BBSs in general. This

may be more satisfying to the average programmer.

Or you can wait for a little while and these manufacturers

are bound to release all there little VBXs as Delphi

components with all the functionality in tack.

Hope this helps.

Steve Wiser

---

 * KWQ/2 1.2g * Bablyon Five, the best of Televison...


How do I close an MDI Child during runtime in Delphi?

#1084.FAQ	From: koterski@genghis (Steve Koterski)

Imran Hussain (imranh@eden.rutgers.edu) wrote:

:       I have an MDI child form in a main form. When I try to

: close the child form, instead of closing it minimizes. Is there

: any way to close it. That is when I open it again, the create procedure

: gets called again.

In the OnClose event procedure for the MDI child Form, include the line:

   Action := caFree;

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


Multiline Lines

#00000001.TIP	From KWolak@mail.cbf.com Thu Aug 24 12:29:38 1995

In article <41bevf$f1n@news.dgsys.com> eweiss@winchendon.com (Eric Weiss) writes:

>From: eweiss@winchendon.com (Eric Weiss)

>Subject: Multiline Lines

>Date: Tue, 22 Aug 95 02:38:13 GMT

>I am looking for a way to make a scrolling componentent such as a scroll box,

>a combo box, a string grid or a draw grid have more than one line in a cell.

>Spreadsheets do it now, so there must be a way.

>Any pointers or suggestions.

Use the Objects property of the the tstrings object, andmake it an owner draw

component - check out the on-line help. It's v similar to putting up a bitmap

in a combobox, except yoour object would multi lines instead of the graphic.


Array in my own component, How ?

#00000002.TIP	From KWolak@mail.cbf.com Thu Aug 24 12:33:29 1995

In article <cmasgras.57.3036AEDC@postbox.acs.ohio-state.edu>,

   cmasgras@postbox.acs.ohio-state.edu (Cris Masgras) wrote:

>I'm creating a non visual component derived from TComponent, the component

>will take X,Y,Z ( point in space ) data, and I'd like to have any given

number

>of points, how do I make an array inside my component

>( I think it has something to do with Index -- which was mentioned in Appendi

>xA of Component Writter's Guide )

Creating an array property means

  1) creating a property of a given type with an index (see Points below);

  2) defining a read access function which will take an index as a parameter

     and return the given type.

  3) defining a write access procedure which will take an index and a value of

     the given types as parameters.

The cool thing is that while your property may be an array, the data that is

behind the property doesn't have to be an array but can be anything you want.

You could create an array property called

  DayNames(DayNumber: smallint): string

and then define a read function that consists of a case statement which

returns the right day name.  Even better you could define a property

  DayNumber(DayName: string): smallint

which uses a string as its "index" and returns the number of the day of the

week for the day name you pass to it.

Here's an example of a Points array property which provides access to a TList

which would contain objects of type TPoint.  Hope this helps.

MyObject = class(TObject)

  FPointList: TList;

protected

  function GetPoints(lIndex: Longint): TPoint;

  procedure SetPoints(lIndex: Longint; ptValue: TPoint);

public

  Points[lIndex: Longint]: TPoint read GetPoints write SetPoints;

end;

function MyObject.GetPoints(lIndex: Longint): TPoint;

begin

  Result := TPoint(FPointList[lIndex]);

end;

procedure MyObject.SetPoints(lIndex: Longint; ptValue: TPoint);

begin

  FPointList[lIndex] := ptValue;

end;


Useful Delphi Unit

#00000003.TIP	From KWolak@mail.cbf.com Fri Aug 25 09:04:59 1995

The following unit contains some useful routines for delphi-users.

The first two routine are for use with an DropDown Combobox. The routine

DropDownListSelection returns the current selected item of the dropDownComboBox

If no slection was made the routine returns an empty string ('').

The second routine will select a string from a dropdowncombobox. If the string

given is not available in the dropdown list then no selection will be made.

The last routine is for use with an TabbedNotebook component.The routine will

set the focus on the given control (component), by first making the tabPage that

contains the comtrol the visible page, and then setting the focus to the control.

If the specified control is noton the TabbedNotebook no changes (focussing) will

be made.

Any reactions on these routines are always welcome,

unit Useful;

interface

uses StdCtrls, TabNotBk, Classes;

  function GetDropDownListSelection(cbList: TComboBox): string;

  procedure SetDropDownListSelection(cbList: TComboBox; Selection: string);

  procedure FocusTabbedNotebookControl(NoteBook: TTabbedNotebook; Control: TComponent);

implementation

uses

  Controls, SysUtils;

  function GetDropDownListSelection(cbList: TComboBox): string;

  var

    Index : Integer;

  begin

    Result := '';

    if cbList.Style = csDropDownList then

    begin

      Index := cbList.ItemIndex;

      If Index >= 0 then Result := cbList.Items.Strings[Index];

    end;

  end;

  procedure SetDropDownListSelection(cbList: TComboBox; Selection: string);

  var

    Index : Integer;

  begin

    Index := cbList.Items.IndexOf(Selection);

    If Index >= 0 then cbList.ItemIndex := Index;

  end;

  procedure FocusTabbedNotebookControl(NoteBook: TTabbedNotebook; Control: TComponent);

  var

    Index, I : Integer;

    Found : Boolean;

    TabPage : TTabPage;

    function ControlPresent( OwnerControl: TControl; ControlToSearchFor: string): Boolean;

    var

      Index: Integer;

      Found: Boolean;

      Ctl: TWinControl;

    begin

      Found := False;

      if OwnerControl is TWinControl then

      begin

        Ctl := TWinControl(OwnerControl);

        if Ctl.ControlCount = 0

          then Found := CompareText( OwnerControl.Name, ControlToSearchFor) = 0

          else

            begin

              index := 0;

              while (not found) and (index < Ctl.ControlCount) do

              begin

                Found := ControlPresent(Ctl.Controls[Index], ControlToSearchFor);

                Inc(Index);

              end;

            end;

      end;

      Result := Found;

    end; {ControlPresent}

  begin {FocusTabbedNotebookControl}

    if Control is TWinControl then

    begin

      if not TWinControl(Control).CanFocus then

      begin

        found := False;

        for index := 0 to NoteBook.Pages.Count-1 do

        begin

          TabPage := TTabPage(NoteBook.Pages.Objects[index]);

          for i := TabPage.ControlCount-1 downto 0 do

          begin

            Found := ControlPresent(TabPage.Controls[i], Control.Name);

            if found then NoteBook.PageIndex := Index;

          end;

        end;

      end;

      if TWinControl(Control).CanFocus then TWinControl(Control).SetFocus;

    end;

  end;  {FocusTabbedNotebookControl}

end.


Tab key in KeyDown event?

#00000004.TIP	From KWolak@mail.cbf.com Fri Aug 25 10:01:06 1995

You can trap any key for any form or any specific component, like this:

Attach a popup menu to the form or component.

Disable the "AutoPopUp" property, wherever it is.

Put a command and description in the menu, something like

        Caption: TAB Key

        Name: ItemTab

In your form's FormCreate event handler, put something like this:

        ItemTab.ShortCut := ShortCut(vk_Tab,[]);

Now, whenever the component or form containing this invisible menu

has the focus, the Tab key will be trapped _first_ by the menu,

and the ItemTab event will be triggered.

Is this in a FAQ somewhere?  (Timo, where are you?)

It's cute, but I had to work it out all by myself.  (>SOB<)

: Eric :

--

------------------------------------------------------------------------------

I can face anything, except the future,  |  Eric the Fruitbat, aka Paul Sleigh

and certain parts of the past            |  In the SCA: Eric of Tobar Mhuire

and present.      -- Ashleigh Brilliant  |  fruitbat@canberra.DIALix.oz.au


TStrings Property Editor(???)

#00000005.TIP	From KWolak@mail.cbf.com Sat Aug 26 15:41:40 1995

KWolak@mail.cbf.com (Kirk Wolak) wrote:

>In article <41kd5v$5ch@nellie.musc.edu>, RAUCHS@MUSC.EDU says...

>>

>>I can'r figure out how Delphi calls it's dialog box for TString

>>properties in the Object Inspector.  I've browsed a bit in the VCL

>>source, but no references are made to such a thing.  Any ideas?

>>

>>Thanks in advance...

>>

>I don't believe you have to do anything.  Just define the property as

>TStrings.  Delphi will automatically supply the reader and the writer

>for it.

>I am checking some code I now... Yeah, look at Outline.pas in the VCL.

>Since Delphi knows what a TString is, it knows how to let you edit them.

>I used a color selection box the same way.  I was impressed that it was

>so easy!

If you're actually interested in the process, check out DSGNINTF.PAS

in the VCL source.  It defines the standard property editors.  The

general idea is to make a dialog box that edits the members of a

class...you make an Edit procedure in your property editor that

instantiates the dialog box.  Delphi calls Edit whenever the ellipsis

is pressed.

Geo

--

George Mealer

gmealer@best.com


Running or Designing, how do I tell?

#00000007.TIP	From KWolak@mail.cbf.com Thu Aug 31 14:03:14 1995

In article <421q67$jr8_001@ramhb.co.nz>, Sean Cross <sean@crm.co.nz> wrote:

>

>I have a component that I wish to draws differently depending on wether my

>application is running or being designed.  How do I tell?

>

>On a slightly related topic, I have a form which i would like to display at

>different times with different layouts (within the same program).  My first

>though was to make it a component and publish the components properties that I

>wish to change.  However this is a fairly painful process as i can't see the

>results of my changes without running the app.  Does anyone have a better way?

>

>Thanks

>

>Sean

Hey Sean,

Try...

  if csDesigning in ComponentState

    then

      begin

        { code for the design phase }

      end

    else

      begin

        { code for the real thing }

      end;

I have not tried this.  Instead I spent a lot of time

getting my component to draw correctly (no mean feat)

during design time.

Mike Leahy


TOutline owner-draw problem

#00000008.TIP	From KWolak@mail.cbf.com Wed Sep 06 10:19:15 1995

In article <seanoDE9Jq7.ELJ@netcom.com>, seano@netcom.com (Sean O'Dell) wrote:

>I've been doing a little Delphi programming and I guess I'm dealing with

>a bug in the TOutline control.  It doesn't seem to want to be owner-drawn.

>

>I get the OnDrawItem message, which I didn't before the patch.  However,

>now the index passed starts at 0, whereas the outline control's Items list

>starts at 1.

It's not documented this way, but the "Index" passed to your OnDrawItem

handler is the row number of the outline item as displayed in your control,

not the index of the outline node in your outline.  If your outline has 50

nodes, but only 3 are displayed (the other 47 being hidden inside collapsed

nodes) then you will get index values of 0, 1, and 2.  To get around this

problem you can convert from the "row index" to the "node index" with the

GetItem method:

  NodeIndex := GetItem(Rect.Left, Rect.Top);

>Also, rectangle area I'm passed is a perfect square;  wide

>and high equal to the ItemHeight property.  If I try and enlarge the

>rectangle to the outline's entire width, any drawing I do outside the

>original rectangle gets painted over with the background brush.

>

There is a definite problem with the setting of the rectangle.  Although my

symptoms were not the same as yours, I found that the problem went away if you

disable the horizontal scrollbar.  Of course that's not acceptable in all

cases, so I'm still working on a workaround.

Brian Murray                      murray@uansv3.vanderbilt.edu

Office of Admnistrative Systems

Vanderbilt University


Using Temporary VB strings from within Delphi

#00000009.TIP	From KWolak@mail.cbf.com Thu Sep 07 13:37:19 1995

I am invoking in a DLL designed for use with VB from within a Delphi app.  The

functions I am calling supposedly return a temporary VB string (TBasicString in

Delphi.)  I am getting valid VB strings for parameters passed in a callback

function from the DLL (the parameters values are created with VBCreateHlstr,) but

all the function return values (created with VBCreateTempHlstr) are NULL.

It appears as though VBCreateTempHlstr fails when not invoked from (a DLL invoked

from) within a VB program.  My guess is that some temporary string space is not

being initialized.

Has anyone else experienced this problem, and more to the point, does anyone have a

solution?


Property TStrings gives error..

#00000010.TIP	From KWolak@mail.cbf.com Fri Sep 08 12:26:12 1995

On 6 Sep 1995 09:47:33 GMT, "Frank.Korpershoek"

<frank.korpershoek@nni.nl> wrote:

>Hello

>

>I have a very simple component which has a property Strings of type TStrings.

>When I add this component to a form and I try to edit the Strings property

>Delphi gives the error 'Cannot assign a nil to a TMemoStrings'. I haven't got a

>clue where this error is coming from, but I realy like to use a TStrings type

>property, so if anyone know what I'm doing wrong, please help.....

>constructor TStringsTest.create(AOwner : TComponent);

>begin

>  inherited create(AOwner);

>  FStrings := TStrings.create;

>end;

You need to create a TStringList instance, not TStrings.

TStrings is an abstract base class and allocates no memory for the

actual strings.  Instead, it defines an interface that its subclasses

(like TStringList) follow.

--

Ray Lischner         (lisch@tempest-sw.com)

Tempest Software, Corvallis, Oregon, USA


Telling IDE of changes & mouse events in design mode

#00000011.TIP	From KWolak@mail.cbf.com Wed Jan 11 11:02:44 1995

root@comu2.auckland.ac.nz (Richard Vowles) writes:

>Two questions which I CANNOT find any info about are the following:

>(1) I have a property editor which brings up a form with a TStringGrid

>    and does various bits and pieces. It saves the info into TStrings

>    and I have the appropriate functions which will save it into the DFM

>    file as a fake property - no problem. The problem comes with telling

>    Delphi that a change has been made - when I do these changes in the

>    property and recompile or hit Ctrl-S, Delphi does not recognise anything

>    has changed and so the compile is wrong (old data) or the save is

>    missed... Anyone (esp. from Borland?) know how to tell Delphi there

>    have been changes?

Try the Modified method of the property editor.  It is documented in the

dsgnintf.pas unit in the docs dir.

>(2) For those with the VCL source code, how does TStringGrid get the

>    mouse events when in DESIGN mode? You can resize the columns in

>    design mode, but when I try and get the mouse events (move for

>    example, even when I go to the WM_MOUSEMOVE level) - I _cannot_ seem

>    to get these events... I can get WM_SETCURSOR, but not WM_MOUSEMOVE.

>    Unfortunatly, to use SETCURSOR I need to have HCURSOR := 0 in

>    CreateParams which works in runtime (again) but not design mode (it

>    is ignored). Not being able to do this means I can't allow the user

>    of the component dynamically resize columns, which means I have a

>    simple property editor which stores things in an array which means

>    I have another 'fake' property which doesn't get saved on change which

>    gets me back to problem 1.

I used the csDesignInteractive flag within the ControlStyle set, which

gives you the right mouse button at design time.  You then must check

for the right mouse button and map it to the left mouse button when

in design mode. WM_SETCURSOR always gets called; you needn't set

HCURSOR to 0.

Here is the code I used within WM_SETCURSOR message:

   if (FResizeState = sprsNormal) then

    inherited

   else

    SetCursor(Screen.Cursors[CursorTable[FResizeState]]);

This gave me the cursors at design time and run time, and if you

changed the cursor properties in the object inspector, the design

time cursor would change.

That said, does anyone know how to get the LEFT mouse button at design

time like the grid?

>Does anyone know of any books that really get technical with Delphi?

>I don't mind investing some money but $1k for VCL source code is a bit

>on the high side for me...

Isn't the VCL source more like $100?

--

Dwayne Mercredi              |  mercredi@nyquist.ee.ualberta.ca

VP External                  |  http://www.ee.ualberta.ca/~mercredi/

Computer Engineering Club    |  ceclub@nyquist.ee.ualberta.ca

University of Alberta        |  http://www.ee.ualberta.ca/~ceclub/


How to add a Splash Screen to my app ??

#00000012.TIP	From KWolak@mail.cbf.com Tue Sep 19 10:25:57 1995

>

>>

>>Hi,

>> any ideas on how to add a spash screen to my Delphi App?

>>thanks!

>  in the Project Source write

>

>  {$R *.RES}

>

>  begin

>     CreditForm := TcreditForm.create(Application);

>     CreditForm.show;

>     CreditForm.update;

>

>     Application.CreateForm(Tform1, form1);

>     :

>

>     CreditForm.Hide;

>     CreditForm.Free;

>     Application.Run;

>  end.

>

I use the same technique. Just a little more info that I use...

If an app loads too fast, and I want to make sure the user gets a

good look at my splash screen (containing copyright, etc.), I add

a timer on the splash screen and set the interval to something like

1500 or 2000 (1.5 sec or 2.0 sec) and set Enabled to false.

Then in the OnTimer event for the timer, I code:

    timer1.enabled := false;

Then, in my project source:

    begin

       splash := tsplash.create(application);

       splash.show;

       splash.update;

       splash.timer1.enabled := true;

       while (splash.timer1.enabled) do

           application.processmessages;       {DON'T forget this!}

       application.createform(tmainform,mainform);

       splash.hide;

       splash.free;

       application.run;

    end.

This has the effect of pausing the splash screen for a few moments

just so the user gets a good look. Don't want to display for too long

or it is annoying. I find that 1.5 seconds works OK for me.

Again, make sure you've got the 'application.processmessages'

statement in the while loop or you've got yourself a loop that won't

wake up.

Hope this helps,

Greg


child forms w/o MDI?

#00000013.TIP	From KWolak@mail.cbf.com Sat Oct 21 22:55:54 1995

hugg@pobox.com (Steven E. Hugg) wrote:

>Anyone have any idea how to make a form a child of another form without using

>MDI?  I just want to make a form that stays on top of its parent without using

>the StayOnTop style (it's really a pain when debugging)!  This does not seem

>possible with Delphi -- the menus in the child form do not work.  Anyone have

>any insight?  I would appreciate it.  Thanks!

>Steve

(Also see my article on 16/10/95 'Separate TForms within

TTabbedNotebook component?')

I've just figured out a way to acheive what I want - I think it's what

you want too. Here's how:

Form1 contains Panel1 (which just happens to reside within a tabbed

notebook). I want to display Form2 within Form1.Panel1.

I have the following in Form2's definition:

  private

    MyParent: TWinControl;

  protected

    procedure CreateParams(var Params: TCreateParams); override;

  public

    constructor CreateAsChild(AOwner: TWinControl);

And the bodies:

constructor TForm2.CreateAsChild(AOwner: TWinControl);

begin

  MyParent := AOwner;

  inherited Create(AOwner);

end;

procedure TForrm2.CreateParams(var Params: TCreateParams);

begin

  inherited CreateParams(Params);

  with Params do

  begin

    WndParent := MyParent.Handle;

    Style := Style or WS_CHILD;

    Style := Style and not WS_POPUP;

  end;

end;

(CreateParams is used to create the params for the call to

CreateWindow in the Windows API)

Now, in Form1, I have:

procedure TForm1.TabSet1Click(Sender: TObject);

begin

  NoteBook1.PageIndex := TabSet1.TabIndex;

  if NoteBook1.PageIndex = 1 then

      Form2 := TForm2.CreateAsChild (Panel1);

  else

  begin

    Form2.free;

    Form2 := nil;

  end

end;

I'm not sure if I'm doing everything I ought to, but this seems to

work ok. Please reply if I'm doing anything wrong! Thanks

Chris


Height of Comboboxes *

#00000014.TIP	From KWolak@mail.cbf.com Sat Oct 21 23:39:57 1995

mark.horridge@buseco.monash.edu.au (Mark.Horridge@buseco.monash.edu.au) wrote:

: In article <Pine.SOL.3.90.951008050310.5346A-100000@eddie> g4smurf@cdf.toronto.edu (Brian Rampersaud) writes:

: >One last thing.  How on *Earth* does one go about changing the height of

: >a listboxes, comboboxees, ... to a height LESS than 21

: I had this problem: it seems that you can't adjust the height of a combo box -

: you adjust the font size and the height follows. Thuswise:

:   {adjust Combo Font until Height=ComboHeight}

: with Combo do begin

:    while (Height < ComboHeight) do Font.Height := Font.Height+1;

:    while (Height > ComboHeight) do Font.Height := Font.Height-1;

: end;

I found this snippet here a short time ago:

From: d4filip@dtek.chalmers.se (Filip Hanik)

Newsgroups: comp.lang.pascal.delphi.components

Subject: DECREASING HIGHT ON COMBOBOXES - PROBLEM SOLVED

Date: 17 Aug 1995 15:25:50 GMT

Organization: Chalmers univ. of Technology

Lines: 17

Message-ID: <40vn1u$itk@nyheter.chalmers.se>

NNTP-Posting-Host: mis.dtek.chalmers.se

X-Newsreader: TIN [version 1.2 PL2]

To all of you who wants smaller comboboxes. Here comes the solution!

In the Function GetMinHeight there's a row looking like this:

Result := Metrics.tmHeight + FTextMargin + GetSystemMetrics(SM_CYBORDER) * 4

+ 1;

Change it to

Result := Metrics.tmHeight;

PROBLEM SOLVED.

Filip Hanik

d4filip@dtek.chalmers.se


Sorted TLists?

#00000015.TIP	From KWolak@mail.cbf.com Tue Nov 07 13:07:45 1995

j_mcarthur@BIX.com (Jeffrey McArthur) wrote:

>Borland Pascal 7.0 had TCollection and TSortedCollection.  Delphi provides

>TList which is a functional replacement for TCollection.  But I could not

>find the equivalant of TSortedCollection.

>

>TStringList does about what I would like.  It has the ability to sort and

>remove duplicate entries.  But I am not dealing with anything that looks

>like a string.  Comparing two objects can be quite complicated.  Now I

>could use a StringList and figure some way of building a string to

>represent the sort order; but that sounds a bit indirect.

>

>Does anyone have a pointer to a unit implementing a SortedList?

>

I have implemented the objects-unit from BP 7.0 under Delphi. You find

it on the Delphi Superpage "http://sunsite.icm.edu.pl/~robert/delphi"

in the freeware section. It's named objects7.zip.

Guy Fink (By kind permission of Alain.Rassel)


Transparent Bitmaps-SOLUTION

#00000016.TIP	From KWolak@mail.cbf.com Sat Oct 21 23:48:47 1995

>I'm looking for a way to overlay bitmap images over one-another with part

>of one bitmap being designated as transparent.  Is there any such Delphi

>VCL out there with this type of functionality?

Hi Everyone,

You can use the following code for transparent bitmaps. It works fine.

Just copy and paste into your code.

{=================================================================}

{This procedure will draw a source bitmap onto a target bitmap,

 leaving information from the taget to shine through where the

 pixels in the source are of the specified transparent color.

 t   = The target bitmap to be drawn onto

 x,y = The position on the target where source is drawn

 s   = The source bitmap

 TrCol = The color that will become transparent in the source bmp

 NOTE: Don't forget to repaint the target, eg Image1.Invalidate}

procedure DrawTransparent(t: TBitmap; x,y: Integer; s: TBitmap; TrCol: TColor);

var

  bmpXOR, bmpAND, bmpINVAND, bmpTarget: TBitmap;

  oldcol: Longint;

begin

  try

   bmpAND        := TBitmap.Create;

   bmpAND.Width  := s.Width;

   bmpAND.Height := s.Height;

   bmpAND.Monochrome := True;

   oldcol := SetBkColor(s.Canvas.Handle, ColorToRGB(TrCol));

   BitBlt(bmpAND.Canvas.Handle, 0,0, s.Width, s.Height,

               s.Canvas.Handle, 0,0, SRCCOPY);

   SetBkColor(s.Canvas.Handle, oldcol);

   bmpINVAND       := TBitmap.Create;

   bmpINVAND.Width := s.Width;

   bmpINVAND.Height:= s.Height;

   bmpINVAND.Monochrome := True;

   BitBlt(bmpINVAND.Canvas.Handle, 0,0, s.Width, s.Height,

             bmpAND.Canvas.Handle, 0,0, NOTSRCCOPY);

   bmpXOR        := TBitmap.Create;

   bmpXOR.Width  := s.Width;

   bmpXOR.Height := s.Height;

   BitBlt(bmpXOR.Canvas.Handle, 0,0, s.Width, s.Height,

               s.Canvas.Handle, 0,0, SRCCOPY);

   BitBlt(bmpXOR.Canvas.Handle, 0,0, s.Width, s.Height,

       bmpINVAND.Canvas.Handle, 0,0, SRCAND);

   bmpTarget        := TBitmap.Create;

   bmpTarget.Width  := s.Width;

   bmpTarget.Height := s.Height;

   BitBlt(bmpTarget.Canvas.Handle, 0,0, s.Width, s.Height,

                  t.Canvas.Handle, x,y, SRCCOPY);

   BitBlt(bmpTarget.Canvas.Handle, 0,0, s.Width,s.Height,

             bmpAND.Canvas.Handle, 0,0, SRCAND);

   BitBlt(bmpTarget.Canvas.Handle, 0,0, s.Width,s.Height,

             bmpXOR.Canvas.Handle, 0,0, SRCINVERT);

   BitBlt(t.Canvas.Handle,   x,y, s.Width, s.Height,

    bmpTarget.Canvas.Handle, 0,0, SRCCOPY);

  finally

   bmpXOR.Free;

   bmpAND.Free;

   bmpINVAND.Free;

   bmpTarget.Free;

  end;{End of TRY section}

end;

{=================================================================}


TOutline - OnDrawItem isn't being called

#00000017.TIP	From KWolak@mail.cbf.com Mon Nov 06 12:20:04 1995

On 2 Nov 1995, Slobodan Celenkovic wrote:

> I am trying to slightly change the outline component's behaviour as far

> as drawing the items is concerned. I followed the instructions from help:

> 1 - set the Style to otOwnerDraw

> 2 - created the OnDrawItem handler

> However the handler is not being called!?! Is this a Delphi bug, or am I

> missing something?

Yes, it is a bug in Delphi, but itis fixed in the patch available at

ftp.borland.com.

- Matt


Can Someone Explain the TWriter/TReader

#00000018.TIP	From KWolak@mail.cbf.com Tue Oct 31 15:10:55 1995

On 18 Oct 1995 04:47:01 GMT, rmcgilli@ix.netcom.com (Rich McGillicuddy

) wrote:

>I have been playing with Streams lately and noticed the TReader and

>TWriter Object. What intrigued me was their ability to save components.

>Could someone post more information on these object(Maybe even streams

>in general) or maybe an example program. I have a couple of Books, The

>Delphi documentation, and BP7 Documentation and none really give

>Streams and their friends justice.

There is on-line documentation, although it is a bit sparse.

To read and write components, you don't need to mess with readers and

writers. Just use TStream.WriteComponent and TStream.ReadComponent.

When reading a component, it is usually best to create it beforehand

and pass the instance to ReadComponent.

If you have an object that does not derive from TComponent, then you

need to write and read it yourself. You can use TReader and TWriter.

They define many methods for reading and writing binary data, with

type safety.

--

Ray Lischner         (lisch@tempest-sw.com)

Tempest Software, Corvallis, Oregon, USA


List of Constants?

#1000.TIP	From: pp000661@pop3.interramp.com (Bob Fabiszak)

In article <3jm6rs$ch1@linda.teleport.com>, ediss@teleport.com says...

>

>The Delphi User's Guide references some constants, for example, clLime

>and clFuchsia.  Where is a list of such constants?  I've looked in the

>docs, in the online help, and for a text file.  Am I blind?

>

This may not be exactly what you wanted, but there should be a directory

called

\DELPHI\DOC, which will have a bunch of files with an .INT extension.  These

appear

to be basically header files containing class definitions, constants,

enumerated

types, and global variables.  Browse them with your favorite text editor and

you

will find scattered among them a number of constants and enumerated types.

You can

also see all of the classes available to you and all of their methods

(including

the "private" methods).  You won't, of course, see the implementation unless

you

bought the source code.  When the VCL Reference Manual ships they might be

listed

in there.

Hope this helps,

Bob


Major crash through Power shortage

#1001.TIP	From: Steve Teixeira <steixeir@borland.com>

Captain Lee <lior@citenet.net> wrote:

>

>

> Well I just got Delphi and let me say it is awesome.  I was just fidling

> around with it and out of the blue I got a power shortage.  When the power

> came back up, Delphi didn't.  I click on the icon and it opens, everything

> looks good but just before it finishes loading, it disappears.  It's not on

> my task lists or anything, it's not minimized, it's just not there.  No

> error messages nothing.  I then click on it again and this time I get an

> error message : 'COMPONENT LIBRARY IS ALREADY IN USE'.  I press OK and it

> loads up but no Form and no speed buttons.  So I was wondering, is there

> anyway to solve the problem or do I just re-install?

>

Whoa... sounds like Bad Things happened when the power went out.  I'd do

a re-install.

        -Steve Teixeira

         steixeir@borland.com


Blocking Default Behavior?

#1002.TIP	From: joser@dorsai.dorsai.org (joser)

In article <3k83q6$ktb@bighorn.terra.net>, Grant Carpenter says:

>

>I've been playing with Delphi for a few weeks now, wandering randomly

>through the documentation (I believe this is what it was designed for, ergo

>the lack of coherence). One thing I haven't found a way to do is to pre-empt

>certain types of behaviors (In ObjectPAL setErrorCode and disableDefault

>allow you to avoid or delay default event handling). Is there an easy way to

>do this or am I getting into API territory?

>

>Specifically, part of my application includes an form that is never intended

>to be restored/max'd. It opens wsMinimized and should stay iconized. When the

>user dblClicks the icon, a different form should open (why? because a CTL3D

>dialog comes with a wierd background for the icon if you change its winState

>at run-time). I've been looking at this from a very OPAL-centric mindset,

>thinking I could just block the resizing in the OnResize event handler, but

>this isn't working (FYI-a Form.Show or .Hide in the OnResize handler isn't

>very popular). How should I be looking at

>

>

>Grant Carpenter

>+++++++++++++++++++++++++++++++++++

>grant@pinadvgrp.com

>gcarpent@interserv.com

>pinnacleMA@aol.com

>

I had similar problems and I blame the poor docs.  Anyway I found that

blocking the default behaviour is easily done by raising a quiet exception

line Abort; (i.e. on the OnCellExit event you can block the user from

leaving the cell by using first the SelectedField property to find if

it is the field you want to validate and if there is a problem just use

the Abort execption. IT WORKED FOR ME

Hope this will help


Win API

#1003.TIP	From: jnhodges@nps.navy.mil (John N. Hodges)

In article sbl@server.icon-stl.net, rzika@icon-stl.net (Ron Zika) writes:

>I've had alot of DOS C and Visual Basic experience but I'm a newbie to

Pascal.

> I would like to know (preferrably a simple code fragment :) ) how to use

>functions like GetPrivateProfileString in the Windows API. But I haven't had

a

>whole lot of luck in Delphi yet.  Any suggestions?

>

If you want to write and read INI files, check out the TInifile object which

encapsulates those API calls.

The entire API is available to you with Delphi.  Check out the help file

that contains all the API calling information.  Click Help|Windows API.

---

*   LT Nick Hodges, USN                     Naval Postgraduate School

*

*   jnhodges@nps.navy.mil                Information Technology Management

*

*   CIS: 71563,2250 AOL: NHodges                   Monterey, CA

*

*   The opinions expressed above are entirely my own and not the Navy's.

*

*   Visit my homepage:  http://vislab-www.nps.navy.mil/~jnhodges

*


Delphi Libraries

#1004.TIP	From: jnhodges@nps.navy.mil (John N. Hodges)

In article 78h@nyheter.chalmers.se, d2axeul@dtek.chalmers.se (Ulf Axelsson)

writes:

>It appears that Delphi doesn't run "w8loss" when recompiling a library.

>(It's size increases about 300K, and apparently a DCL is a DLL which is a NE)

>

>Could anyone tell me if there is an option for this, or if there will be an

>update ?

>

Check "Optimize for Size and Speed", or something like that, on the Project

Options/Linker page

---

*   LT Nick Hodges, USN                     Naval Postgraduate School

*

*   jnhodges@nps.navy.mil                Information Technology Management

*

*   CIS: 71563,2250 AOL: NHodges                   Monterey, CA

*

*   The opinions expressed above are entirely my own and not the Navy's.

*

*   Visit my homepage:  http://vislab-www.nps.navy.mil/~jnhodges

*


GREAT SECRET of Delphi

#1005.TIP	From: ftpadm6@ftp (FTP Manager #6)

Try typing following command under your delphi/bin directory:

C>copy delphi.dsl tpp.tpl

C>copy con a.pas

program a;

begin

  writeln('Delphi DPMI!?');

end.

^Z

C>dcc -cp a

You will get a 16-bit DPMI executable!

Though, it cannot be executed, for the runtime lib linked into it is for

Windows. However, it's possible that, we may modify slight source code on

system unit, such that we may use dcc to produce DPMI executables, and,

it's possible for those who own a copy of RTL source code, to rebuild the

whole RTL into TPPs!

G R E A T   S E C R E T !!!!!!


Executing Another Windows App

#1006.TIP	From: jim@cstl.demon.co.uk (Jim Smith)

In article <3km2dh$t1g_001@remote.ualberta.ca>

           dtessman@gpu.srv.ualberta.ca "Dean Tessman" writes:

> I am new to pascal programming (ObjectView Background - basic based). Could

> someone please spare the minute it would take to help me with a very basic

> task.  I want my Delphi app to execute another windows application with a

> button click.  I have spent the last 4+ hours browsing on-line help, demos,

> and this group.

>

I stole the following code from the filmanex example (fmxutil.pas) :

function ExecuteFile(const FileName, Params, DefaultDir: string;

  ShowCmd: Integer): THandle;

var

  zFileName, zParams, zDir: array[0..79] of Char;

begin

  Result := ShellExecute(Application.MainForm.Handle, nil,

    StrPCopy(zFileName, FileName), StrPCopy(zParams, Params),

    StrPCopy(zDir, DefaultDir), ShowCmd);

end;

Called with the code :

   executeFile('maker.exe','text_file','c:\maker', SW_SHOWNORMAL);

Hope this helps.

--

Jim Smith


Can you delay the OnHint Event?

#1007.TIP	From: jnhodges@nps.navy.mil (John N. Hodges)

In article 100000@zeus.towson.edu, "Travis L. Reno" <reno@zeus.towson.edu>

writes:

>I am using a TPanel to display fly-by hints for it's controls.  Is it

>possible to delay the OnHint Event so that the fly-by help is only

>displayed after, say, 1 second of leaving the mouse on the same control?

>

>Forgive me if this is an RTFM.  I am still using the last beta version

>because I haven't received my final copy yet. And the beta docs are still

>pretty sketchy in some areas.

>

I _think_ that the form has a property to set the amount of time of the delay.

I am not at home to verfiy this, but look at the Object Inspector for the form

and see if there is such a property.

---

*   LT Nick Hodges, USN                     Naval Postgraduate School

*

*   jnhodges@nps.navy.mil                Information Technology Management

*

*   CIS: 71563,2250 AOL: NHodges                   Monterey, CA

*

*   The opinions expressed above are entirely my own and not the Navy's.

*

*   Visit my homepage:  http://vislab-www.nps.navy.mil/~jnhodges

*

From: jnhodges@nps.navy.mil (John N. Hodges)

In article ion@nps.navy.mil, jnhodges@nps.navy.mil (John N. Hodges) writes:

 >I _think_ that the form has a property to set the amount of time of the

delay.

>

>I am not at home to verfiy this, but look at the Object Inspector for the

form

>and see if there is such a property.

>

>

Let me follow up my own post with the correct answer --

Application.HintDelay = {milliseconds} will set the hint delay value.

---

*   LT Nick Hodges, USN                     Naval Postgraduate School

*

*   jnhodges@nps.navy.mil                Information Technology Management

*

*   CIS: 71563,2250 AOL: NHodges                   Monterey, CA

*

*   The opinions expressed above are entirely my own and not the Navy's.

*

*   Visit my homepage:  http://vislab-www.nps.navy.mil/~jnhodges

*


Errorlevel final version

#1008.TIP	From: DFAURE@cipcinsa.insa-lyon.fr (David Faure)

UNIT UError;

Interface

Var Seg_Psp_Command,Adr_ErrorLevel,Version_Dos,Revision_Dos:Word;

Function Search_Seg_Psp_Command:Word;

Procedure Search_Adr_ErrorLevel;

Function Get_ErrorLevel:Word;

Implementation

Uses dos,crt;

Const offset_psp_father:Word=$16;

        offset_seg_env:Word=$2C;

Function Search_Seg_Psp_Command:Word;

Var CurrentPsp,SearchPsp:Word;

Begin

        CurrentPsp:=PrefixSeg;

        Repeat

                SearchPsp:=CurrentPsp;

                CurrentPsp:=MemW[CurrentPsp:offset_psp_father];

        Until CurrentPsp=SearchPsp;

        Search_Seg_Psp_Command:=SearchPsp;

End;

Function Search_Dos56:Word;

Var Seg_Dos56,ofs_dos56:Word;

Begin

  ofs_dos56:=MemW[seg_Psp_Command:$114];

  seg_dos56:=MemW[seg_Psp_Command:$116];

  Search_Dos56:=MemW[Seg_Dos56:Ofs_Dos56+7];

End;

Function Search_Dos34:Word;

Begin {Tell me if you're interested}

End;

Procedure Search_Adr_ErrorLevel;

Begin

     Version_Dos:=Lo(DosVersion);

     Revision_Dos:=Hi(DosVersion);

     Adr_ErrorLevel:=0;

     Seg_Psp_Command:=Search_Seg_Psp_Command;

     If version_Dos>4 then

         Adr_ErrorLevel:=Search_Dos56

      else Adr_ErrorLevel:=Search_Dos34; {not included}

End;

Function Get_Errorlevel:word;

Begin

     Search_adr_ErrorLevel;

     Get_ErrorLevel:=MemW[Seg_psp_command:adr_errorlevel];

End;

BEGIN

END.

Uses UError;

Begin

        Writeln('ErrorLevel Value :',GetErrorLevel);

End.

David Faure

DFaure@cipcinsa.insa-lyon.fr

From: DFAURE@cipcinsa.insa-lyon.fr (David Faure)

I tested my Uerror unit, and there were

some little errors:

Replace in Search_Seg ...

at line 'Until'    := by =

Replace Procedure Get_ErrorLevel by

  Function Get_ErrorLevel:Word;

In that Function, Replace Error:=  by Get_ErrorLevel:=   and delete next line

(Writeln)

In main program, Write :

Begin

        Writeln('ErrorLevel Value: ',Get_ErrorLevel);

End.

Hope this helps ...


.pas to printer??

#1009.TIP	From: phil@nexussft.demon.co.uk (Phillip Simon Smith)

I use a LJ4L for printing and I am able to print from Delphi,  my

problem is that printing is VERY slow. It takes almost 1 min. per

page, very strange for straight text.

My setup is 16Mb, 486/40.  I am using the 'Windows Printing System'

as supplied with my LJ4L.

Sorry, that didn't help much!

-- Phil Smithphil@nexussft.demon.co.uk,    also

sometimes G8JSL

nexus - "a bond, link or connection"


Tip A-#1: using .hlp

#1010.TIP	From: keeper@netcom.com (Mark R. Johnson)

For all of you Delphi users out that who are frustrated with the

documentation, etc.  I have a big tip for you.  Open up the delphi.hlp

file in WinHelp (\delphi\bin\delphi.hlp, or F1 from the Delphi IDE).

Now READ the Contents page.

I know this sounds stupid, but it seems that a lot of the material

people claim isn't in the online docs is right there.  Let's see...

  o <Essentials> and concepts  you need to know         <--- !!!

    before you start building Delphi applications.

  o <Building Applications> provides help on

    designing, coding, and debugging

    applications, as well as managing projects

    and files.

  o <Programming Environment> provides help on

    using the Delphi development environment.

  o <Delphi Visual Component Library> reference.        <--- !!!

  o <Tools> reference.

  o <Object Pascal Language> reference of terms.        <--- !!! Language

                                                                 Reference

  o <Glossary>

There's some great stuff here.  It appears to be actually very well

written if you approach it from page 1 like this.  (The Search and

Search All may be somewhat lacking, on the other hand, but them's

the breaks.)

I hope everyone finds this tip useful!

--Mark Johnson

______________________________________________________________________________

Mark R. Johnson   |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/

Atlanta, GA USA   |\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\

keeper@netcom.com |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/


Graphics Unit

#1011.TIP	From: The Green Meddler <kilgalen@tde.com>

vadim@media.mit.edu (Vadim Gerasimov) wrote:

>

> I need to work with DIBs in memory.

> Graphics Unit has GetDIB and MemAlloc, but I could not find

> the reverse operations. It looks incomplete.

have you checked the windows api? a lot of the graphics and

memory functions are there rather than in the units. the only

ones in the units are those, IMHO, which needed to be redefined

to work with the vcl?

> How should I dispose MemAlloc blocks?

> Why MemAlloc is in Graphics?

> Can I graciously modify DIB associated with TBitmap?

all VCL object have a Handle property which you can send to

the standard API calls. I have successfully coerced a TBitmap

handle into the api and worked with it.

> It would be nice to have a full set of DIB operations in TBitmap,

> and MemAlloc/MemReAlloc/MemDispose in SysUtils.

> AllocMem/ReAllocMem from SysUtils are defined with type Cardinal.

my version returns bool. this is a true/false value. haven't heard

of cardinal.

> Is it the same as Word? Is it gonna be unsigned 32-bit integer in

> later versions?

>

> -Vadim

GM

From: vadim@media.mit.edu (Vadim Gerasimov)

In article <3k0kij$t4s@tdelx01.tde.com>, The Green Meddler <kilgalen@tde.com>

says:

>all VCL object have a Handle property which you can send to

>the standard API calls. I have successfully coerced a TBitmap

>handle into the api and worked with it.

TBitmap is supposed to "encapsulate" the handles, so that I can

avoid using them directly. If I use SetDIBits from API, I have to

dig out DC, deselect the bitmap from the DC, etc. The problem is

that the source code for TBitmap is not included and I have to

guess how it will behave if I actively change some of its

properties.

>> AllocMem/ReAllocMem from SysUtils are defined with type Cardinal.

>my version returns bool. this is a true/false value. haven't heard

>of cardinal.

function AllocMem(Size: Cardinal): Pointer;

                        ^^^^^^^^

function StrLen(Str: PChar): Cardinal;

                             ^^^^^^^^

Looks very useful, but undocumented. I guess it's the same as Word in

the current version of Delphi

-Vadim


Misc/Tips - Stretching 256 color bitmaps
Stretching 256 color bitmaps

#1012.TIP	From: The Green Meddler <kilgalen@tde.com>

canalrun@aol.com (CanalRun) wrote:

>

> Hello everyone,

>

> I am having a problem stretching 256 color bitmaps in TImage components

> within Delphi. I am wondering if this is a universal problem or just me.

> It

> appears on both computers I have tried. They are closely conifgured

> though.

> Could someone please try the following experiment.

>

> 1) Open a new project in Delphi.

>

> 2) On Form1, create a single TImage component. Make the rectangle slightly

> larger (or smaller) than the bitmap you plan to load.

>

> 3) Load a 256 color bitmap into the TImage component. On my system the

> bitmap displays properly at this point. (Stretch property = false). It is

> top-left

> justified, does not fill the entire TImage rectangle, and the colors are

> correct. I am using a bitmap of Diamond Head in Hawaii. Everything

> displays

> as expected.

>

> 4) Set the Stretch property = true. The bitmap stretches to fill the

> TImage

> rectangle properly, but the colors are now incorrect. The water is gray,

> mountains gray, sand is green.

>

> 5) Set the Stretch property = false. The bitmap displays top-left

> justified

> properly as in #3 above.

>

> The same bitmap displays and stretches properly in Photo Shop (a

> Paint-like

> program) and it displays and stretches properly in an MSVC program I wrote

> 1

> year ago. On my system the symtoms seem to mimic the SetStretchBltMode()

> being set to STRETCH_ORSCANS instead of STRETCH_DELETESCANS.

>

> I have tried the above experiment compiling and running the stretched and

> non-stretched TImage components to isolate possible "design time"

> differences. I get the same incorrect results.

>

> Is this error particular to my system? Is it just a "user" error on my

> part?

> Is there a workaround I can use to make 256 color stretched bitmaps

> display correctly on my machine.

>

> My video setup is 800 x 600 x 256 Diamond Viper VLB.

>

> Thanks for any help and suggestions,

> Barry.

check out the documentation about palettes and the Timage control.

i suspect there may be a problem when the bitmap is stretched

with getting the wrong palette. this is why the problem persists

when you go back to normal.

and i have viper too, and i have SERIOUS problems with it. never

again...

GM


Misc/Tips - Stretching 256 color bitmaps
Stretching 256 color bitmaps

#1013.TIP	From: canalrun@aol.com (CanalRun)

>If I set the stretch property of an image to true and load a 256 color

>picture into it, the colors are messed up. This happens whether the

>image is smaller or larger than the picture. It's a bit difficult to

>see exactly what is happening, but it looks like the palette is reduced

>to 16 (wrong) colors.

>

>I've tried different video cards, because in another thread it was said

>that the problem was caused by the drivers, but it makes no difference.

>I am currently using an ET4000 and the default MS SVGA drivers.

>

>Wonder how many other people get this problem? The 'splash' images

>supplied with Delphi are a nice size for testing.

I have the same problems with the Diamond Viper. Updated Viper drivers

solve the problem.

Someone using the Generic Windows SVGA also had this problem.

I wonder what Borland has to say? I can't see using Delphi for an

application if it only works on "some" systems!

Barry.


Printing in cm's (inches)?

#1014.TIP	From: jochenh@berlin.snafu.de (Jochen Heyland)

Kimmo Lahtinen (Kimmo.Lahtinen@fmi.fi) wrote:

: I was hoping to see a little improvement in Delphi 1.0 with

: Canvas.MoveTo command, but it still works with pixels. So I wonder

: how to find out printers pixel/inch so that I could convert

: them by myself?

: There is probably some suitable API calls, but I have not find them.

: Actually I can not understand why the printer dialog can not return

: this information as it displays it.

: Kimmo Lahtinen

Still don't have my Delphi :-( but I do know this one:

SetMapMode determines whether to use pixels, millimeters or inches.  2

comments on it though:

1.Anything but pixels (MM_text) flips the direction of the Y-axis, ie

down becomes negative.  Annoying.

2. You'll need to call LPtoDP lots of places to calculate how stuff

should be output.  Windows seems totally incosistent as to when it

expects logical points (mm,inc) and when device points (pixels,points).

If I missed some rule to this, please let me know as I'm currently going

into the help every time I do anything...

Jochen

 --

-----------------------------------------------------------------------

jochenh@berlin.snafu.de                       74754.2016@compuserve.com

jochen@cs.umd.edu                             Voice: +49 30 7816904


Run Multiple Delphi.exe

#1015.TIP	From: vic@r-node.io.org (Vic Metcalfe)

Jin Mai (mwj@nyc.pipeline.com) wrote:

:

: Is it possible to run more than delphi.exe at once with each

: Delphi open different projects?

No.  Trying to execute a second instance just brings the first back up.

This would be really useful so that you could have a DLL's project up at

the same time as the application which is using it.  I have used two machines

on a lan to get around this, each copy of delphi working from the same

directory.  (Source directory I mean, not Delphi directory!)

Regards,

  Vic.

From: Steve Teixeira <steixeir@borland.com>

mwj@nyc.pipeline.com (Jin Mai) wrote:

>

>

> Is it possible to run more than delphi.exe at once with each

> Delphi open different projects?

>

No problem.  Are you running Windows NT 3.5? OS/2 Warp?  In a nutshell, Delphi

doesn't support multiple instances under standard Windows 3.1x.

        -Steve Teixeira

         steixeir@borland.com


Compare two blocks of code

#1016.TIP	From: moscow@aed.org (Moscow)

Dion Kurczek (dionkk@ix.netcom.com) wrote:

: In <3l1egd$577@pipe4.nyc.pipeline.com> mwj@nyc.pipeline.com (Jin Mai)

: writes:

: >

: >

: >I just start to use Delphi. One question for Delphi real

: >programmers, have you ever try to compare two blocks

: >of code? Delphi keeps only one unit code window open.

: >whenever I have to copy and past between units, I have

: >to switch the unit tab pages. Is there any short cut?

: >

: >

: Simply choose the View, New Edit Window menu item.  Hope this helps!

Try Ctrl-Tab or Ctrl-Shift-Tab

Gorik

(gorik@cs.msu.su Gor V. Nishanov)


Image Editor Reboots Computer

#1017.TIP	From: Steve Teixeira <steixeir@borland.com>

mac@zeus.hsrc.ac.za (Malcolm Coulter) wrote:

>

> In article <3l52pp$bls@crucible.inmind.com> mwatts@inmind.com (Mark Watts -

Ventus Corporation) writes:

> >From: mwatts@inmind.com (Mark Watts - Ventus Corporation)

> >Subject: BORLAND: Image Editor Reboots Computer

> >Date: 27 Mar 1995 01:01:45 GMT

>

> >Delphi is Great!!

>

> >Except for one problem.  I know that the image editor has been reported

> >to have some problems, but on my system it can be counted on to reboot my

> >computer.  This is the ONLY problem that I have had will Delphi thus far

> >in my experiments.  My question is this: Is Borland going ship an

> >upgrade/patch for the bugs that are found and if so when, and were will

> >it be announced.

> ---------------------------------------------------------------------

> I had this problem and "cured" it by making sure that there was sufficient

> disk space free on my Windows drive (where the TEM directory is also). This

> may not be the only problem with the Image Editor, but it's worth checking

> your disk space first.

Additionally, the problem may be a video driver conflict.  Try using the

standard

VGA driver and see if the problem goes away.

        -Steve Teixeira


Help moving Title-barless Form

#1018.TIP	From: moscow@aed.org (Moscow)

Gary L. McMillan (mcmillan@eskimo.com) wrote:

: Looking for suugestions for how to move a form with no titlebar.

: I've come close but I can't get it right.

: mcmillan@eskimo.com

Write your handler of WMNCHITTEST message.

You need to return HTCAPTION value.

Gorik

(Gor V.Nishanov gorik@cs.msu.su)


Preventing User from Maximizing Forms

#1019.TIP	From: ao@atlas.sto.foa.se (Anders Ohlsson)

In article <3l4rn1$6qa@ixnews2.ix.netcom.com>, jleon@ix.netcom.com (John Leon)

writes:

|> In <3l4s42$lbq@news.compulink.com> sblazer@idirect.com (Star Blazer)

|> writes:

|>

|> >

|> >Could someone please tell me how to prevent a user from MAXIMIZING a

|> >program?  I've looked through the on-line help, but couldn't find which

|> >property I would have to change.  I would like my program to run with

|> >it's initial window size.  I don't want to allow the user to MAXIMIZE

|> >it.  Thanks for any suggestions.

|> >

|>

|> When designing the form, set the BorderStyle to bsSingle.  This is

|> precisely what you want ... a window that cannot be resized at all, but

|> can be minimized.

This is NOT what he wants.

Setting the BorderStyle to bsSingle only gives you a window with a thin border

and no resizing 'corners'... HOWEVER, the Maximize/Minimize buttons will NOT

be

disabled when you do this.

What he wants is to set BorderIcons - biMaximize to False, that removes the

maximize button from the title bar. If he also wants to prevent resizing he

has to set BorderStyle to bsSingle as you said. The resulting window can only

be minimized and restored.

-----------------------------------------------------------------------------

!  The Windoze program you want is at http://www.it.kth.se/~ao/yacpu20.zip  !

!                                                                           !

!          Anders Ohlsson - ao@sto.foa.se - http://www.it.kth.se/~ao        !

-----------------------------------------------------------------------------


Beware infinite event loops!

#1020.TIP	From: Marc@landscap.demon.co.uk (Marc Palmer)

In article: <3lflt8$hdl@clarknet.clark.net>  garyc@clark.net (Gary

Cramblitt) writes:

>

> This suggestion could save you hours of frustration and

> head-scratching:

>

> Here, I was trying to datestamp each record as it viewed by the user.

> When I ran it, my program not only crashed but Windows itself.  A hard

> reboot was required.  After a lot of rebooting, I realized that my

> problem was an infinite event loop.  The code in the DataChange event

> was causing another DataChange event, which caused another DataChange

> event, etc., until the stack overflowed.  The fix is to prevent this

> reentrancy, like this:

[snip]

Why don't you put your code in the OnPost( or is it BeforePost) event?

Much less hassle.

********************************************************************

* Marc P.                               E-Mail me for PGP 2.6 key  *

*                                                                  *

* "Most of the ideas I have at the moment have to do with things   *

* that are completely impossible, so I am wary about sharing them. *

* They are, however, the only thoughts I have." - Dirk Gently      *

********************************************************************


FORMS - DRAGGING WITHOUT CLICKING THE CAPTION BAR

#2000.TIP	From BORLAND

{

 Q: How can I make a form move by clicking and dragging in the client area

    instead of on the caption bar?

 A: The easiest way to do this is to "fool" Windows into thinking that

    you're actually clicking on the caption bar of a form.  Do this by

    handling the wm_NCHitTest windows message as shown in the sample unit

    below.

    TIP: If you want a captioness borderless window similar to a floating

    toolbar, set the Form's Caption to an empty string, disable all of the

    BorderIcons, and set the BorderStyle to bsNone.

}

unit Dragmain;

interface

uses

  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,

  Forms, Dialogs, StdCtrls;

type

  TForm1 = class(TForm)

    Button1: TButton;

    procedure Button1Click(Sender: TObject);

  private

    procedure WMNCHitTest(var M: TWMNCHitTest); message wm_NCHitTest;

  end;

var

  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.WMNCHitTest(var M: TWMNCHitTest);

begin

  iinherited;                    { call the inherited message handler }

  if  M.Result = htClient then  { is the click in the client area?   }

    M.Result := htCaption;      { if so, make Windows think it's     }

                                { on the caption bar.                }

end;

procedure TForm1.Button1Click(Sender: TObject);

begin

  Close;

end;

end.

{ The text representation of the .DFM file is below:

object Form1: TForm1

  Left = 203

  Top = 94

  BorderIcons = []

  BorderStyle = bsNone

  ClientHeight = 273

  ClientWidth = 427

  Font.Color = clWindowText

  Font.Height = -13

  Font.Name = 'System'

  Font.Style = []

  PixelsPerInch = 96

  TextHeight = 16

  object Button1: TButton

    Left = 160

    Top = 104

    Width = 89

    Height = 33

    Caption = 'Close'

    TabOrder = 0

    OnClick = Button1Click

  end

end

}


MAKING DELPHI APPS SHOW MINIMIZED

#2002.TIP	From BORLAND

Q: When I select the "Run Minimized" option in Program Manager

   to attempt to make my Delphi application execute in a minimized

   state, the Delphi application seems to ignore the setting and

   run normally.  Why is this, and how to I fix it?

A: Delphi's Application object creates a hidden "application

   window," and it is that window, rather than your main form,

   that is being sent the command to show minimized. To fix this,

   just enter this line of code in your main form's OnCreate event handler:

     ShowWindow(Handle, cmdShow);


HOW TO MATCH FILE DATE/TIME STAMPS

#2006.TIP	From BORLAND

{

Q: "How can I write a function that sets the date of one file equal to the

   date of another file?"

A: No problem.  Just use the following function, which takes two strings

   representing full DOS path/file names.  The file who's date you

   wish to set is the second parameter, and the date you wish to set it to

   is given by the file in the first parameter.

}

procedure CopyFileDate(const Source, Dest: String);

var

  SourceHand, DestHand: word;

begin

  SourceHand := FileOpen(Source, fmOutput);       { open source file }

  DestHand := FileOpen(Dest, fmInput);            { open dest file }

  FileSetDate(DestHand, FileGetDate(SourceHand)); { get/set date }

  FileClose(SourceHand);                          { close source file }

  FileClose(DestHand);                            { close dest file }

end;


USING ONHINT EVENTS AMONG MULTIPLE FORMS

#2007.TIP	From BORLAND

Delphi's Online Help and Visual Component Library Reference

describe an example for processing TApplication's OnHint event.

The example shows how a panel can be used to display hints

associated with other components. As the example sets the

Application's OnHint method in the Form's OnCreate event, a

program involving more than one form will have difficulty using

this technique.

Moving the assignment of OnHint from the Form's OnCreate event

to its OnActivate method will allow different forms involved in

the application to treat Hints in their own way.

Here is an altered form of the source code presented in the

Online Help and the VCL Reference.

type

  TForm1 = class(TForm)

    Button1: TButton;

    Panel1: TPanel;

    Edit1: TEdit;

    procedure FormActivate(Sender: TObject);

  private

    { Private declarations }

  public

    procedure DisplayHint(Sender: TObjject);

  end;

implementation

{$R *.DFM}

procedure TForm1.DisplayHint(Sender: TObject);

begin

  Panel1.Caption := Application.Hint;

end;

procedure TForm1.FormActivate(Sender: TObject);

begin

  Application.OnHint := DisplayHint;

end;


MAKING THE ENTER KEY WORK LIKE A TAB IN A TDBGRID

#2008.TIP	From BORLAND

{

This code also includes the processing of the <Enter> key for the entire

application - including fields, etc.  The grid part is handled in the

ELSE portion of the code.  The provided code does not mimic the behavior

of the <Tab> key stepping down to the next record when it reaches the last

column in the grid - it moves back to the first column - .

}

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);

{ This is the event handler for the FORM's OnKeyPress event! }

{ You should also set the Form's KeyPreview property to True }

begin

  if Key = #13 then                              { if it's an enter key }

    if not (ActiveControl is TDBGrid) then begin { if not on a TDBGrid }

      Key := #0;                                 { eat enter key }

      Perform(WM_NEXTDLGCTL, 0, 0);              { move to next control }

    end

    else if (ActiveControl is TDBGrid) then      { if it is a TDBGridd }

      with TDBGrid(ActiveControl) do

        if selectedindex < (fieldcount -1) then  { increment the field }

          selectedindex := selectedindex +1

        else

          selectedindex := 0;

end;


MOVING TO A TAB BY NAME ON A TABSET

#2009.TIP	From BORLAND

Place a Tabset(TabSet1) and an Edit (Edit1) on

your form. Change the Tabset's Tabs Property in

the String List Editor to include 4 Tabs:

             Hello,

             World,

             Of,

             Delphi,

Change Edit1's onChange event to:

procedure TForm1.Edit1Change(Sender: TObject);

var

  I : Integer;

begin

  for  I:= 0 to tabset1.tabs.count-1 do

   if  edit1.text = tabset1.tabs[I] then

     tabset1.tabindex:=I;

end;

If You type any of the Tabs names in edit1 it

will focus on the appropriate tab.


ENCRYPTING STRINGS

#2011.TIP	From BORLAND

{

 Here is a program that demonstrates routines for encryption and

 decryption of strings. Note: Author claims no responsibily for the

 security of these functions.

}

program Crypt;

uses WinCRT;

const

  C1 = 52845;

  C2 = 22719;

function Encrypt(const S: String; Key: Word): String;

var

  I: byte;

begin

  Result[0] := S[0];

  for I := 1 to Length(S) do begin

    Result[I] := char(byte(S[I]) xor (Key shr 8));

    Key := (byte(Result[I]) + Key) * C1 + C2;

  end;

end;

function Decrypt(const S: String; Key: Word): String;

var

  I: byte;

begin

  Result[0] := S[0];

  for I := 1 to Length(S) do begin

    Result[I] := char(byte(S[I]) xor (Key shr 8));

    Key := (byte(S[I]) + Key) * C1 + C2;

  end;

end;

var

  S: string;

begin

  Write('>');

  ReadLn(S);

  S := Encrypt(S,12345);

  WriteLn(S);

  S := Decrypt(S,12345);

  WriteLn(S);

end.


UNDO IN A MEMO FIELD

#2012.TIP	From BORLAND

  If you have a pop-up menu in a TMemo, and put shortcuts

on it for the Cut,Copy, Paste, then you can handle those

events, and call CuttoClipBoard, CopytoClipBoard, etc.

  However, if you put an Undo option onto your pop-up menu

(normally Ctrl-Z) how do you instruct the TMemo to do the Undo?

If the built-in undo is sufficient, you can get it easier than

a Ctrl+Z:

    Memo1.Perform(EM_UNDO, 0, 0);

 To check whether undo is available so as to enable/disable

an undo menu item:

    Undo1.Enabled := Memo1.Perform(EM_CANUNDO, 0, 0) <> 0;


GETTING LINE NUMBER IN A MEMO

#2013.TIP	From BORLAND

{

  How do you figure out what line number you are currently

  on with a TMemo control?

  The trick is to use the em_LineFromChar message.  Try this:

}

procedure TMyForm.BitBtn1Click(Sender: TObject);

var

  iLine : Integer ;

begin

   iLine := Memo1.Perform(em_LineFromChar, $FFFF, 0);

   { Note: First line is zero }

   messageDlg('Line Number: ' + IntToStr(iLine), mtInformation,

              [mbOK], 0 ) ;

end;


PRINTING CONTENTS OF A TMEMO OR TLISTBOX

#2015.TIP	From BORLAND

{

 The function below accepts a TStrings object as a parameter and prints

 out each string to the default printer.  Because it uses a TStrings, the

 function will work with any type of component that contains a

 TStrings-type property, such as a TDBMemo or TOutline.

}

uses Printers;

procedure PrintStrings(Strings: TStrings);

var

  Prn: TextFile;

  i: word;

begin

  AssignPrn(Prn);

  try

    Rewrite(Prn);

    try

      for i := 0 to Strings.Count - 1 do

        writeln(Prn, Strings.Strings[i]);

    finally

      CloseFile(Prn);

    end;

  except

    on EInOutError do

      MessageDlg('Error Printing text.', mtError, [mbOk], 0);

  end;

end;

{ End code listing }

To print out the contents of a TMemo or TListbox, use the following

code:

PrintStrings(Memo1.Lines);

or

PrintStrings(Listbox1.Items);


Misc/Tips - EXTRACTING A BITMAP FROM A BLOB FIELD
EXTRACTING A BITMAP FROM A BLOB FIELD

#2016.TIP	From BORLAND E-Mail:

Extracting a bitmap from a dBASE or Paradox blob field -- without first

saving the bitmap out to a file -- is a simple process of using the Assign

method to store the contents of the BLOB field to an object of type

TBitmap. A stand-alone TBitmap object or the Bitmap property of the

Picture object property of a TIMage component are examples of compatible

destinations for this operation.

Here is an example demonstrating using the Assign method to copy a bitmap

from a BLOB field into a TImage component.

  procedure TForm1.Button1Click(Sender: TObject);

  begin

    Image1.Picture.Bitmap.Assign(Table1Bitmap);

  end;

In this example, the TBLOBField object Table1Bitmap is a BLOB field in a

dBASE table. This TBLOBField object was created using the Fields Editor.

If the Fields Editor is not used to create TFields for the fields in the

table, the fields must be referenced using either the FieldByName method

or the Fields property, both part of the TTable and TQuery componentts. In

cases where one of those means is used to reference the BLOB field in a

table, the field reference must be type-cast as a TBLOBField object prior

to using the Assign method. For example:

  procedure TForm1.Button1Click(Sender: TObject);

  begin

    Image1.Picture.Bitmap.Assign(TBLOBField(Table1.Fields[1]));

  end;

A bitmap stored in a BLOB field may also be copied directly to a stand-

alone TBitmap object. Here is an example showing the creation of a

TBitmap object and storing into it a bitmap from a BLOB field.

  procedure TForm1.Button2Click(Sender: TObject);

  var

    B: TBitmap;

  begin

    B := TBitmap.Create;

    try

      B.Assign(Table1Bitmap);

      Image1.Picture.Bitmap.Assign(B);

    finally

      B.Free;

    end;

  end;


CONTROL FONT STYLES

#2017.TIP	From BORLAND

{

  This code will change the font style of a Edit

  when selected. This code could be implemented to

  control font style on other objects.

  With a Edit(Edit1) and a ListBox(ListBox1) on a form

  Add the following Items to the ListBox:

    fsBold

    fsItalic

    fsUnderLine

    fsStrikeOut

}

procedure TForm1.ListBox1Click(Sender: TObject);

var

  X : Integer;

type

  TLookUpRec = record

    Name: String;

    Data: TFontStyle;

  end;

const

  LookUpTable: array[1..4] of TLookUpRec =

  ((Name: 'fsBold'; Data: fsBold),

   (Name: 'fsItalic'; Data: fsItalic),

   (Name: 'fsUnderline'; Data: fsUnderline),

   (Name: 'fsStrikeOut'; Data: fsStrikeOut));

begin

  X := ListBox1.ItemIndex;

  Edit1.Text := ListBox1.Items[X];

  Edit1.Font.Style := [LookUpTable[ListBox1.ItemIndex+1].Data];

end;


HOW TO HANDLE TEXT DRAWING IN A TDBGRID

#2018.TIP	From BORLAND

{

  The following method can be used as the event handler for a

  TDBGrid.OnDrawDataCell event.  This method demonstrates how

  to paint the text in one column a different color than the

  rest of the text in the grid.

}

procedure TForm1.DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect;

  Field: TField; State: TGridDrawState);

{ NOTE: DefaultDrawing propery of Grid(s) must be set to False }

begin

  { if field name is "NAME" }

  if Field.FieldName = 'NAME' then

    { change font color to red }

    (Sender as TDBGrid).Canvas.Font.Color := clRed;

  { draw text in the grid }

  (Sender as TDBGrid).Canvas.TextRect(Rect, Rect.Left + 2, Rect.Top + 2,

                                      Field.AsString);

end;


SEARCHING YOUR APPLICATION'S HELP FILE

#2020.TIP	From BORLAND

{

  The following code demonstrates how to bring up the WinHelp "Search"

  dialog for your application's help file.  You can use TApplication's

  HelpCommand method to send the Help_PartialKey command to the WinHelp

  system. The parameter for this command should be a PChar (cast to a

  longint to circumvent typechecking) that contains the string on

  which you'd like to search.  The example below uses an empty string,

  which invokes "Search" dialog and leaves the edit control in the

  dialog empty.

}

procedure TForm1.SearchHelp;

var

  P: PChar;

begin

  Application.HelpFile := 'c:\delphi\bin\delphi.hlp';

  P := StrNew('');

  Application.HelpCommand(Help_PartialKey, longint(P));

  StrDispose(P);

end;


MANAGING DISK VOLUME LABELS

#2029.TIP	From BORLAND

{

 This document contains the source code for a unit that is useful for

 getting, setting, and deleting volume labels from a floppy or hard disk.

 The code for getting a volume label uses the Delphi FindFirst function,

 and the code for setting and deleting volume labels involves calling DOS

 interrupt 21h, functions 16h and 13h respectively.  Since function 16h

 isn't supported by Windows, it must be called through DPMI interrupt 31h,

 function 300h.

}

unit VolLabel;

interface

uses Classes, SysUtils, WinProcs;

type

  EInterruptError = class(Exception);

  EDPMIError = class(EInterruptError);

  Str11 = String[11];

procedure SetVolumeLabel(NewLabel: Str11; Drive: Char);

function GetVolumeLabel(Drive: Char): Str11;

procedure DeleteVolumeLabel(Drv: Char);

implementation

type

  PRealModeRegs = ^TRealModeRegs;

  TRealModeRegs = record

    case Integer of

      0: (

        EDI, ESI, EBP, EXX, EBX, EDX, ECX, EAX: Longint;

         Flags, ES, DS, FS, GS, IP, CS, SP, SS: Word);

      1: (

        DI, DIH, SI, SIH, BP, BPH, XX, XXH: Word;

        case Integer of

          0: (

            BX, BXH, DX, DXH, CX, CXH, AX, AXH: Word);

          1: (

            BL, BH, BLH, BHH, DL, DH, DLH, DHH,

            CL, CH, CLH, CHH, AL, AH, ALH, AHH: Byte));

  end;

  PExtendedFCB = ^TExtendedFCB;

  TExtendedFCB = Record

    ExtendedFCBflag : Byte;

    Reserved1       : array[1..5] of Byte;

    Attr            : Byte;

    DriveID         : Byte;

    FileName        : array[1..8] of Char;

    FileExt         : array[1..3] of Char;

    CurrentBlockNum : Word;

    RecordSize      : Word;

    FileSize        : LongInt;

    PackedDate      : Word;

    PackedTime      : Word;

    Reserved2       : array[1..8] of Byte;

    CurrentRecNum   : Byte;

    RandomRecNum    : LongInt;

  end;

procedure RealModeInt(Int: Byte; var Regs: TRealModeRegs);

{ procedure invokes int 31h function 0300h to simulate aa real mode }

{ interrupt  from protected mode. }

var

  ErrorFlag: Boolean;

begin

  asm

    mov ErrorFlag, 0       { assume success }

    mov ax, 0300h          { function 300h }

    mov bl, Int            { real mode interrupt to execute }

    mov bh, 0              { required }

    mov cx, 0              { stack words to copy, assume zero }

    les di, Regs           { es:di = Regs }

    int 31h                { DPMI int 31h }

    jnc @@End              { carry flag set on error }

  @@Error:

    mov ErrorFlag, 1       { return false on error }

  @@End:

  end;

  if ErrorFlag then

    raise EDPMIError.Create('Failed to execute DPMI interrupt');

end;

function DriveLetterToNumber(DriveLet: Char): Byte;

{ function converts a character drive letter into its numerical equiv. }

begin

  if DriveLet in ['a'..'z'] then

    DriveLet := Chr(Ord(DriveLet) -32);

  if not (DriveLet in ['A'..'Z']) then

    raise EConvertError.CreateFmt('Cannot convert %s to drive number',

                                  [DriveLet]);

  Result := Ord(DriveLet) - 64;

end;

procedure PadVolumeLabel(var Name: Str11);

{ procedure pads Volume Label string with spaces }

var

  i: integer;

begin

  for i := Length(Name) + 1 to 11 do

    Name := Name + ' ';

end;

function GetVolumeLabel(Drive: Char): Str11;

{ function returns volume label of a disk }

var

  SR: TSearchRec;

  DriveLetter: Char;

  SearchString: String[7];

  P: Byte;

begin

  SearchString := Drive + ':\*.*';

  { find vol label }

  if FindFirst(SearchString, faVolumeID, SR) = 0 then begin

    P := Pos('.', SR.Name);

    if P > 0 then begin                      { if it has a dot... }

      Result := '           ';               { pad spaces between name }

      Move(SR.Name[1], Result[1], P - 1);    { and extension }

      Move(SR.Name[P + 1], Result[9], 3);

    end

    else begin

      Result := SR.Name;                     { otherwise, pad to end }

      PadVolumeLabel(Result);

    ennd;

  end

  else

    Result := '';

end;

procedure DeleteVolumeLabel(Drv: Char);

{ procedure deletes volume label from given drive }

var

  CurName: Str11;

  FCB: TExtendedFCB;

  ErrorFlag: WordBool;

begin

  ErrorFlag := False;

  CurName := GetVolumeLabel(Drv);        { get current volume label }

  FillChar(FCB, SizeOf(FCB), 0);         { initialize FCB with zeros }

  with FCB do begin

    ExtendedFCBflag := $FF;              { always }

    Attr := faVolumeID;                  { Volume ID attribute }

    DriveID := DriveLetterToNumber(Drv); { Drive number }

    Move(CurName[1], FileName, 8);       { must enter volume label }

    Move(CurName[9], FileExt, 3);

  end;

  asm

    push ds                              { preserve ds }

    mov ax, ss                           { put seg of FCB (ss) in ds }

    mov ds, ax

    lea dx, FCB                          { put offset of FCB in dx }

    mov ax, 1300h                        { function 13h }

    Call DOS3Call                         { invoke int 21h }

    pop ds                               { restore ds }

    cmp al, 00h                          { check for success }

    je @@End

  @@Error:                               { set flag on error }

    mov ErrorFlag, 1

  @@End:

  end;

  if ErrorFlag then

    raise EInterruptError.Create('Failed to delete volume name');

end;

procedure SetVolumeLabel(NewLabel: Str11; Drive: Char);

{ procedure sets volume label of a disk.  Note that this procedure }

{ deletes the current label before setting the new one.  This is }

{ required for the set function to work. }

var

  Regs: TRealModeRegs;

  FCB: PExtendedFCB;

  Buf: Longint;

begin

  PadVolumeLabel(NewLabel);

  if GetVolumeLabel(Drive) <> '' then           { if has label... }

    DeleteVolumeLabel(Drive);                   { delete label }

  Buf := GlobalDOSAlloc(SizeOf(PExtendedFCB));  { allocate real buffer }

  FCB := Ptr(LoWord(Buf), 0);

  FillChar(FCB^, SizeOf(FCB), 0);                { init FCB with zeros }

  with FCB^ do begin

    ExtendedFCBflag := $FF;                     { required }

    Attr := faVolumeID;                         { Volume ID attribute }

    DriveID := DriveLetterToNumber(Drive);      { Drive number }

    Move(NewLabel[1], FileName, 8);             { set new label }

    Move(NewLabel[9], FileExt, 3);

  end;

  FillChar(Regs, SizeOf(Regs), 0);

  with Regs do begin                            { SEGMENT of FCB }

    ds := HiWord(Buf);                          { offset = zero }

    dx := 0;

    ax := $1600;                                { function 16h }

  end;

  RealModeInt($21, Regs);                       { create file }

  if (Regs.al <> 0) then                        { check for success }

    raise EInterruptError.Create('Failed to create volume label');

end;

end.


COPYING FILES

#2030.TIP	From BORLAND

{

  Example #1 - uses a File stream

}

Procedure FileCopy( Const sourcefilename, targetfilename: String );

Var

  S, T: TFileStream;

Begin

  S := TFileStream.Create( sourcefilename, fmOpenRead );

  try

    T := TFileStream.Create( targetfilename,

                             fmOpenWrite or fmCreate );

    try

      T.CopyFrom(S, S.Size ) ;

    finally

      T.Free;

    end;

  finally

    S.Free;

  end;

End;

{

  Example #2 - uses memory blocks for read/write

}

procedure FileCopy(const FromFile, ToFile: string);

 var

  FromF, ToF: file;

  NumRead, NumWritten: Word;

  Buf: array[1..2048] of Char;

begin

  AssignFile(FromF, FromFile);

  Reset(FromF, 1);	{ Record size = 1 }

  AssignFile(ToF, ToFile);	{ Open output file }

  Rewrite(ToF, 1);	{ Record size = 1 }

  repeat

    BlockRead(FromF, Buf, SizeOf(Buf), NumRead);

    BlockWrite(ToF, Buf, NumRead, NumWritten);

  until (NumRead = 0) or (NumWritten <> NumRead);

  CloseFile(FromF);

  CloseFile(ToF);

end;

{

  Example #3 - uses LZCopy, which USES LZExpand

}

procedure CopyFile(FromFileName, ToFileName: string);

var

  FromFile, ToFile: File;

begin

  AssignFile(FromFile, FromFileName); { Assign FromFile to FromFileName }

  AssignFile(ToFile, ToFileName);     { Assign ToFile to ToFileName }

  Reset(FromFile);                    { Open file for input }

  try

    Rewrite(ToFile);                  { Create file for output }

    try

      { copy the file an if a negative value is returned }

      { raise an exception }

      if LZCopy(TFileRec(FromFile).Handle, TFileRec(ToFile).Handle) < 0

        then

        raise EInOutError.Create('Error using LZCopy')

    finally

      CloseFile(ToFile);  { Close ToFile }

    end;

  finally

    CloseFile(FromFile);  { Close FromFile }

  end;

end;


POINTER ARITHMETIC

#2031.TIP	From BORLAND

Q:  How do I do pointer arithmetic in Delphi?

A:  First a brief explanation of pointer arithmetic.  When you

are dealing with dynamic memory locations and all you have is a

pointer to where it all begins, you want to have the ability to

traverse that line of memory to be able to perform whatever

functions you have in mind for that data.  This can be

accomplished by changing the place in memory where the pointer

points.  This is called pointer arithmetic.

The main idea that must be kept in mind when doing your pointer

arithmetic is that you must increment the pointer's value by

the correct amount.  (The correct amount is determined by the

size of the object receiving the pointer.  e.g.  char = 1 byte;

integer = 2 bytes; double = 8 bytes;  etc.)  The Inc() and

Dec() functions will alter the amount by the correct amount.

(The compiler knows what the correct size is.)

For an example of the practical application of pointer

arithmetic, download the BreakAApart() TI2905.

If you are doing dynamic memory allocation, it is done like this:

uses WinCRT;

procedure TForm1.Button1Click(Sender: TObject);

var

  MyArray: array[0..30] of char;

  b: ^char;

  i: integer;

begin

  StrCopy(MyArray, 'Lloyd is the greatest!'); {get something to point to}

  b := @MyArray; { assign the pointer to the memory location }

  for i := StrLen(MyArray) downto 0 do

  begin

    write(b^);   { write out the char at the current pointer location. }

    inc(b);      { point to the next byte in memory }

  end;

end;

The following code demonstrates that the Inc() and Dec() functions

will increment or decrement accordingly by size of the type the pointer

points to:

var

  P1, P2 : ^LongInt;

  L : LongInt;

begin

  P1 := @L; { assign both pointers to the same place }

  P2 := @L;

  Inc(P2);  { Increment one }

{ Here we get the difference between the offset values of the

two pointers.  Since we originally pointed to the same place in

memmory, the result will tell us how much of a change occured

when we called Inc(). }

  L := Ofs(P2^) - Ofs(P1^); { L = 4; i.e. sizeof(longInt) }

end;

You can change the type to which P1 and P2 point to something other than a

longint to see that the change is always the correct value (SizeOf(P1^)).


FORM DISPLAY WITH DIFFERENT SCREEN RESOLUTIONS

#2032.TIP	From BORLAND

When designing forms, it is sometimes helpful to write the code

so that the screen and all of its objects are displayed at the

same size no matter what the screen resolution is.  Here is

some code to show how that is done:

implementation

const

  ScreenWidth: LongInt = 800; {I designed my form in 800x600 mode.}

  ScreenHeight: LongInt = 600;

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);

begin

  scaled := true;

  if (screen.width <> ScreenWidth) then

  begin

    height := longint(height) * longint(screen.height) div ScreenHeight;

    width := longint(width) * longint(screen.width) div ScreenWidth;

    scaleBy(screen.width, ScreenWidth);

  end;

end;

Then, you will want to have something that checks to see that

the font sizes are OK.  Before you change the font's size, you

would need to ensure the object actually has a font property.

This can be done as follows:

uses typinfo;

var

  i: integer;

begin

  for i := componentCount - 1 downtto 0 do

    with components[i] do

    begin

      if GetPropInfo(ClassInfo, 'font') <> nil  then

        font.size := (NewFormWidth DIV OldFormWidth) * font.size;

    end;

end;

Note:  The following are issue to bear in mind when scaling

Delphi applications (forms) on different screen resolutions:

  * Decide early on in the form design stage whether you're

going to allow the form to be scaled or not.  The advantage of

not scaling is that nothing changes at runtime.  The

disadvantage of not scaling is that nothing changes at runtime

(your form may be far too small or too large to read on some

systems if it is not scaled).

  * If you're NOT going to scale the form, set Scaled to False.

  * Otherwise, set the Form's Scaled property to True.

  * Set AutoScroll to False.  AutoScroll = True means 'don't

change the form's frame size at runtime' which doesn't look

good when the  form's contents do change size.

  * Set the form's font to a scaleable TruueType font, like

Arial.   MS San Serif is an ok alternate, but remember that it

is still a  bitmapped font.  Only Arial will give you a font

within a pixel of the desired height.  NOTE: If the font used

in an application is not installed on the target computer, then

Windows will select an  alternative font within the same font

family to use instead.  This font may not match the same size

of the original font any may cause problems.

  * Set the form's Position property to something other than

poDesigned.  poDesigned leaves the form where you left it at

design time, which for me always winds up way off to the left

on my 1280x1024 screen -  and completely off the 640x480 screen.

  * Don't crowd controls on the form - leave at least 4 pixels

between  controls, so that a one pixel change in border

locations (due to  scaling) won't show up as ugly overlapping

controls.

  * For single line labels that are alLeft or alRight aligned,

set AutoSize to True.  OOtherwise, set AutoSize to False.

  * Make sure there is enough blank space in a label component

to allow for font width changes - a blank space that is 25% of

the length of the current string display length is a little too

much, but safe. (You'll need at least 30% expansion space for

string labels if you  plan to translate your app into other

languages) If AutoSize is  False, make sure you actually set

the label width appropriately.  If AutoSize is True, make sure

there is enough room for the label  to grow on its own.

  * In multi-line, word-wrapped labels, leave at least one line

of blank space at the bottom.  You'll need this to catch the

overflow when the text wraps differently when the font width

changes with scaling. Don't assume that because you're using

large fonts, you don't have to allow for text overflow -

somebody else's large  fonts may be larger than yours!

  * Be careful about opening a project in the IDE at different

resolutions.  The  form's PixelsPerInch property will be

modified as soon as the form is opened, and will be saved to

the DFM if you save the project. It's best to test the app by

running it standalone, and edit the form at only one

resolution. Editing at varying resolutions and font sizes

invites component drift  and sizing problems.

  * Speaking of component drift, don't rescale a form multiple

times, at design time or a runtime.  Each rescaling introduces

roundoff errors which accumulate very quickly since coordinates

are  strictly integral.  As fractional amounts are truncated

off control's origins and sizes with each successive

rescaling,  the controls will appear to creep northwest and get

smaller. If you want to allow your users to rescale the form

any number  of times, start with a freshly loaded/created form

before each  scaling, so that scaling errors do not accumulate.

  * Don't change the PixelsPerInch property of the form, period.

  * In general, it is not  necessary to design forms at any

particular resolution, but it is crucial that you review their

appearance at 640x480 with small fonts and large, and at a

high-resolution with small fonts and large before releasing

your app.  This should be  part of your regular system

compatibility testing checklist.

  * Pay close attention to any components that are essentially

single-line TMemos - things like TDBLookupCombo.  The Windows

multi-line edit control always shows only whole lines of text

-  if the control is too short for its font, a TMemo will show

nothing at all (a TEdit will show clipped text). For such

components, it's better to make them a few pixels too large

than to be one pixel too small and show not text at all.

  * Keep in mind that all scaling is proportional to the

difference  in the font height between runtime and design time,

NOT the pixel resolution or screen size.  Remember also that

the origins of your controls will be changed when thhe form is

scaled - you can't very well make components bigger without

also moving them over a bit.


HOW TO TERMINATE ALL RUNNING APPLICATIONS

#2034.TIP	From BORLAND

{

  A word of caution, before you run this for the first time, make sure

  that you save it and anything else that may have some pending data.

}

procedure TForm1.ButtonKillAllClick(Sender: TObject);

var

  pTask   : PTaskEntry;

  Task    : Bool;

  ThisTask: THANDLE;

begin

  GetMem (pTask, SizeOf (TTaskEntry));

  pTask^.dwSize := SizeOf (TTaskEntry);

  Task := TaskFirst (pTask);

  while Task do

  begin

    if pTask^.hInst = hInstance then

      ThisTask := pTask^.hTask

    else

      TerminateApp (pTask^.hTask, NO_UAE_BOX);

    Task := TaskNext (pTask);

  end;

  TerminateApp (ThisTask, NO_UAE_BOX);

end;


HOW TO CHECK IF A DRIVE IS READY

#2035.TIP	From BORLAND

{

  The following function accepts a drive letter as a parameter,

  and it will return a boolean value that indicates whether

  or not there is a disk in the drive.

}

function DiskInDrive(Drive: Char): Boolean;

var

  ErrorMode: word;

begin

  { make it upper case }

  if Drive in ['a'..'z'] then Dec(Drive, $20);

  { make sure it's a letter }

  if not (Drive in ['A'..'Z']) then

    raise EConvertError.Create('Not a valid drive ID');

  { turn off critical errors }

  ErrorMode := SetErrorMode(SEM_FailCriticalErrors);

  try

    { drive 1 = a, 2 = b, 3 = c, etc. }

    if DiskSize(Ord(Drive) - $40) = -1 then

      Result := False

    else

      Result := True;

  finally

    { restore old error mode }

    SetErrorMode(ErrorMode);

  end;

end;


BIT-WISE MANIPULATION

#2036.TIP	From BORLAND

{******************************************

TheBit parameter is counted from 0..31

******************************************}

unit Bitwise;

interface

  function IsBitSet(const val: longint; const TheBit: byte): boolean;

  function BitOn(const val: longint; const TheBit: byte): LongInt;

  function BitOff(const val: longint; const TheBit: byte): LongInt;

  function BitToggle(const val: longint; const TheBit: byte): LongInt;

implementation

function IsBitSet(const val: longint; const TheBit: byte): boolean;

begin

  result := (val and (1 shl TheBit)) <> 0;

end;

function BitOn(const val: longint; const TheBit: byte): LongInt;

begin

  result := val or (1 shl TheBit);

end;

function BitOff(const val: longint; const TheBit: byte): LongInt;

begin

  result := val and ((1 shl TheBit) xor $FFFFFFFF);

end;

function BitToggle(const val: longint; const TheBit: byte): LongInt;

begin

  result := val xor (1 shl TheeBit);

end;

end.


HOW TO KEEP APPS ICONIZED

#2037.TIP	From BORLAND

1.  You must set WindowState to wsMinimized in the form's properties.

2.  In the private section of the form object's declaration, put:

      PROCEDURE WMQueryOpen(VAR Msg : TWMQueryOpen); message WM_QUERYOPEN;

3.  In the implementation section, put this method:

      PROCEDURE TForm1.WMQueryOpen(VAR Msg : TWMQueryOpen);

      begin

        Msg.Result := 0;

      end;

That's it! The form will always remain iconic.


ADDING TIME AND DATE STAMP TO MEMOS

#2038.TIP	From Bruce Onder E-Mail: bonder@mail.earthlink.net

{ The following code inserts a date/time stamp into a memo field. }

Var

        s : string ;

begin

        s :=  DateToStr( Date ) + ' ' + TimeToStr( Time ) + '  :' ;

        Memo1.Lines.Insert( 0,  s ) ;

        Memo1.SetFocus ;

        Memo1.SelStart := Length( s ) ;

        Memo1.SelLength := 0 ;


RECURSIVELY REMOVING FILES AND SUBDIRECTORIES

#2039.TIP	From Sid Gudes E-Mail: cougar@roadrunner.com

{

  Has anyone run across a function that will recursively remove files and

  directories given a starting subdirectory path.

  This is adapted from some code I wrote for Borland Pascal 5.5 under DOS (the

  original code didn't do rmDir, so you might want to experiment with where

  the directory pointer goes after the rmDir at the end of the function).  I

  suspect that the Delphi version is either identical or has a few changes in

  function name(s) (check the Delphi help for file management functions).

  This doesn't check for attributes being set, which might preclude deletion

  of a file.  (In Pascal 5.5, you'd put a {$I-} {$I+} pair around the

  functions that cause the problem; don't know if you do that in Delphi.)

}

procedure removeTree (DirName: string);

var

   FileSearch:  SearchRec;

begin

   { first, go through and delete all the directories }

   chDir (DirName);

   FindFirst ('*.*', Directory, FileSearch);

   while (DosError = 0) do begin

      if (FileSearch.name <> '.') AND (FileSearch.name <> '..') AND

         ( (FileSearch.attr AND Directory) <> 0)

      then begin

         if DirName[length(DirName)] = '\' then

            removeTree (DirName+FileSearch.Name)

         else

            removeTree (DirName+'\'+FileSearch.Name);

         ChDir (DirName);

      end;

      FindNext (FileSearch)

   end;

   { then, go through and delete all the files }

   FindFirst ('*.*', AnyFile, FileSearch);

   while (DosError = 0) do begin

      if (FileSearch.name <> '.') AND (FileSearch.name <> '..') then

         Remove (workdir);

      end;

      FindNext (FileSearch)

   end;

   rmDir (DirName)

end;


CHARTFX EXAMPLE

#2040.TIP	From John Y. Ching E-Mail: jyching@watnow.uwaterloo.ca

The instructions that came with Delphi help is indeed a bit encrypted,

particularly if you are not a VBX user...

Any way, the following example should set the values etc for ChartFX:

{The code gets data from a database and plots it}

begin

MyTable.active := True;	{open database}

MyTable.first;

MyChart.title[CHART_BOTTOMTIT] := 'X-axis label';

MyChart.title[CHART_LEFTTIT] := 'Y-axis label';

MyChart.OpenData[COD_XVALUES] := MakeLong(numOfSeries,numofPoints);

MyChart.OpenData[COD_VALUES] := MakeLong(numOfSeries, NumofPoints);

MyChart.ThisSerie := SeriesNum;	{start with 0}

While MyTable.EOF <> True do

begin

     MyChart.value[i] := MyTable.FieldByName('SOMEFIELD').AsFloat;

     MyChart.Xvalue[i] := MyTable.FieldByName('SOMEOTHERFIELD').AsFloat;

     MyTable.next;

     i:=i+1;	{you need to define and initialize 'i' of course}

end;

MyChart.CloseData[COD_Values] := 0;

MyChart.CloseData[COD_XValues] := 0;

MyTable.active := False;	{close database}

end;

{Note this code is for an xy scatter chart. If you want to use any other

type of chart in ChartFX, you will not need to set values for COD_XVALUES}


GETTING A DEVICE CONTEXT FOR A CONTROL

#2041.TIP	From Caracena@henge.com E-Mail: Caracena@henge.com

>Does anyone know how to get a DC for a delphi VCL.  I am trying to use

>the API function StretchBlt which requires a destDC and a sourceDC.

>How do I tell windows to use my TImage or TShape for this purpose?

{Bitmap in a TImage}

HDC := TImage.Picture.bitmap.canvas.handle;

A DC is anything with a Canvas.handle.


DISABLING NAVIGATOR BUTTONS

#2042.TIP	From UNKNOWN

To disable (not hide) a Navigator button, declare a new type like so:

type TDBNavCracker = class(TDBnavigator);

Now you can use it on any navigator control:

TDBNavCracker(DBNavigator1).Buttons[nbEdit].Enabled := false;


DBGRID THAT SHOWS IMAGES

#2043.TIP	From W. Raike E-Mail: UNKNOWN

{

// DBPICGRD.PAS (C) 1995 W. Raike

//              ALL RIGHTS RESERVED.

//

//    DESCRIPTION:

//      Data-aware grid that can display graphic fields.

//    REVISION HISTORY:

//      15/04/95  Created.    W. Raike

}

unit DBPicGrd;

interface

uses

  DBGrids, DB, DBTables, Grids, WinTypes, Classes, Graphics;

type

  TDBPicGrid = class(TDBGrid)

  protected

    procedure DrawDataCell(const Rect: TRect;

      Field: TField; State: TGridDrawState); override;

  public

    constructor Create(AOwner : TComponent); override;

  published

    property DefaultDrawing default False;

  end;

procedure Register;

implementation

constructor TDBPicGrid.Create(AOwner : TComponent);

begin

  inherited Create(AOwner);

  DefaultDrawing := False;

end;

procedure TDBPicGrid.DrawDataCell(const Rect: TRect; Field: TField;

State: TGridDrawState);

var

  bmp : TBitmap;

begin

  with Canvas do

  begin

    FillRect(Rect);

    if Field is TGraphicField then

        try

          bmp := TBitmap.Create;

          bmp.Assign(Field);

          Draw(Rect.Left, Rect.Top, bmp);

        finally

          bmp.Free;

        end

    else

      TextOut(Rect.Left, Rect.Top, Field.Text);

  end;

end;

procedure Register;

begin

  RegisterComponents('Custom', [TDBPicGrid]);

end;

end.


TRANSPARENT WINDOW

#2044.TIP	From UNKNOWN E-Mail: UNKNOWN

To create a transparent window, put 'Brush.Style:=bsClear;' in the OnCreate

event for the form.


GETWINDOWSDIRECTORY

#2045.TIP	From Ben Licht E-Mail: benl@panix.com

{this code finds the windows directory on the click of a button}

procedure TForm1.Button1Click(Sender: TObject);

var

   buf : array[0..200] of char;

   pc : Pchar;

   str : string;

   x : integer;

begin

   pc := @buf[0];

   x := getwindowsdirectory(pc, 199);

   str := strpas(pc);

   writeln(str); { output c:\windows}

   writeln(x);   { output 10}

end;


CONFIGURING AN ODBC DRIVER AND ALIAS FOR DELPHI

#2046.TIP	From BORLAND

CONTROL PANEL'S ODBC OPTION

Delphi installs an ODBC option to the Windows Control Panel

program. The ODBC option indicates the available data sources

(drivers) installed for use by ODBC. As you will find by

selecting the ODBC option, a number of formats are installed

with Delphi and are seen in the main window titled Data Sources.

Additional formats may be supported by the drivers installed and

can be configured by selecting the Add... button.

If a new driver is to be added or removed,

1. Select the Drivers... button from the Data Sources Window.

From the drivers dialog, select the Add... button and provide

the path where the ODBC driver will be found.

2. Return to the Data Sources Windows and include the possible

data sources available through the new driver by selecting its

Add... button.

3. To configure options available for a particular data

source use the Setup... button. The function of the Setup...

button will vary with each data format. Very often options like

the working directory for the driver are configured in this

area.

Online help is available for each dialog involved with the ODBC

option.

BDE CONFIGURATION UTILITY

After installing the ODBC driver, run the BDE Configuration

utility to configure the database engine to use the new driver.

1. From the drivers page, select the New ODBC driver button.

2. A dialog titled Add ODBC driver will appear. The option for

SQL link driver is what will distinguish the databases created

using this ODBC driver.

3. Next select the default ODBC driver. Dropping down the list

from the combobox will reveal the file types supported by ODBC

drivers installed on the system.

4. Select the default data source for the ODBC driver. Having

set the ODBC driver in step 3 above, the list of this combobox

will have the data source names appropriate for use with the

selected driver.

5. Select Ok.

6. Returning to the drivers page, select File/Save from the main

menu to save this configuration.

CREATING AN ALIAS IN THE DATABASE DESKTOP

While this can be done from the BDE Configuration utility, it is

more convenient overall to create ODBC aliases from the Database

Desktop.

1. From the File menu, select Aliases...

2. From the resulting Alias Manager dialog, select New.

3. Type the name for your new alias in the area labeled Database

Alias.

4. Use the drop down list of the Driver Type combobox to select

the driver appropriate for this alias. Paradox and dBase tables

are considered STANDARD. If the ODBC driver was properly

configured in the BDE Configuration utility its name will

appear in this list.

5. Additional options may appear depending upon the driver type

you select.

6. When finished, select Keep New to store the new alias. Then

select Ok. You will be prompted for whether or not to save the

aliases to IDAPI.CFG. Select Okay.

The alias will now be usable from both the Database Desktop and

Delphi.


CONNECTING TO ACCESS 2.0 DATABASES VIA ODBC

#2047.TIP	From Lance Leverich E-Mail: lancel@pdainc.com

With this method, I have connected to Access 2.0 databases, and been able to read and

write records to my hearts content.  NOTE: You MUST have the proper ODBC

drivers.  If you don't, this will not work!

REQUIRED DRIVERS:

      ODBCJT16.DLL   dated 11/18/94 or later

      ODBCINST.DLL   dated 08/17/94 or later

      ODBCCTL16.DLL  dated 11/18/94 or later

      MSAJT200.DLL      dated 11/18/94 or later

      MSJETERR.DLL   dated 11/18/94 or later

      MSJETINT.DLL      dated 11/18/94 or later

To the best of my knowledge, these are all of the drivers that are above and

beyond your base ODBC drivers.  You should be able to obtain these from MS

on their FTP/WWW site, however I do not know exact directories.  My company

is a MS Solutions Provider, and we obtained these drivers on one of the many

CDs we received from MS.

Now for the meat of this posting:

To access a database via ODBC, you must first create an ODBC connection to

the database.

   1) Open Control Panel, and then select ODBC.

   2) When the Data Sources dialog appears, select Add.

   3) If you have installed all of the drivers properly, you should see the

following Access drivers:

         Access Data (*.mdb)

         Access Files(*.mdb)

         Microsoft Access Driver (*.mdb)

   4) The one you MUST choose is the third one, Microsoft Access Driver.

Choosing any of the others will not work.

   5) You will then be presented with the ODBC Microsoft Access 2.0 Setup

dialog.  Fill this in with the information regarding the database to which

you wish to connect.

   6) Save the settings and then exit all the way out of Control Panel.

After having made a proper connection to the database with ODBC, the rest is

quite simple.

   7) Open BDE Config.

   8) Choose New ODBC Driver.

   9) Give your SQL link a name

   10) From the Default ODBC Driver combo box, you must choose the Microsoft

Access Driver, just the same as you did in the ODBC setup.  Do not choose

Access Data/Files drivers.

   11) If everything is setup properly, the name of your database should

appear in the Default Data Source Name combo box.  Select it now.

   12) Select OK, you will be back to the main dialog for BDE Config.

Select the aliases tab.

   13) Create a new alias, using the SQL link that you just created (it will

start with ODBC_) as your Alias Type.

   14) Now save and exit from BDE Config.

You should now be able to get to you Access 2.0 database with both read and

write instructions.

And finally...

I must say that having got to Access, via ODBC, you will probably wish you

hadn't.  It is sssllllooowww.  Anytime we start adding layers, it gets

slower and slower.  Normally, I would recommend staying away from VB like

the plague (I'm an old C++ hacker of many years, and the term BASIC makes me

shudder).  However, at this point in time, the best way to use Access

databases is through either Access or VB.  Microsoft is very close-mouthed

about the structure of Access databases, and there is no indication that

they are planning to change ("You either use VB/Access or we'll make you pay

through the ODBC monster!").  Sorry, I digress.  My recommendation, if you

absolutely MUST use Access, then use VB.  Otherwise, migrate your database

to a more open system (Paradox,dBase/FoxPro,anything you can get a native

engine), and use Delphi.

I hope this helps those who are still having problems accessing Access

databases via ODBC.  If I've left anything out, I would appreciate

commentary. Good Luck!


CREATING A SYSTEM MODAL APPLICATION

#2048.TIP	From The Nomad E-Mail: tnomad@digital.net

>I need to set the application system modal, so the system is

>still secure while allowing anyone to access the program.

Ok, in light of this, here's a couple of suggestions:

a) Create a form that consumes the screen (presumably 640x480) without any

icons (maximize, minimize, system).

b) In the FormDeactivate handler for the form, call the setFocus method as

follows - this will disable Ctrl-Esc:

Form1.SetFocus;

c) In the FormActivate, you must assign the Deactivate method to the

application as follows:

Application.onDeactivate := FormDeactivate;

d) Create a popup menu with one item.  The properties for the item must

include Visible ->False.  Create a function for the single item and have it do

something trivial (x := 1) to prevent the code from being stripped by Delphi.

e) Assign the Popup menu to the form using the Popupmenu property.

f) Create a shortcut for the popup menu in the FormActivate method as follows:

    NullItem1.shortcut := ShortCut(VK_Tab, [ssAlt]);

(Note: NullItem1 should be replaced by the menu item you created).

Steps d, e, and f disable Alt-Tab.


ASSERTIONS IN DELPHI

#2049.TIP	From Jay Cole E-Mail: vandewb@wkuvx1.wku.edu

The definitive Assert.  Better than the line numbers supplied w/ the

C/C++ Assert, this assert gives you the "find|error" logical address

of the calling module that called assert.  It returns the ssss:oooo

seg offset pair so you can find where the assert was called.  Again,

you can use the ifopt D+ if you wish but I prefer a define _NDEBUG

instead.  Hopefully this is the end-all assert. Use freely, just drop

me an e-mail at vandewb@wku.wkuvx1.edu if you find it useful.

{ Call if you need to verify implied conditions }

procedure Assert(assertedCond : boolean; const msgStr : string);

implementation

{$ifdef WINDOWS}

   uses WinProcs, SysUtils, WinTypes;

{$else}

   uses sysUtils;

{$endif}

{ Error when the assumption made is not correct. }

procedure Assert(assertedCond : boolean; const msgStr : string);

var

   msgOut : array[0..300] of char;

   hexStr : array[0..30] of char;

   progSeg, progOfs : word;

   tmpStr : string;

begin

   { Get the logical segment used by the Find|Error menu option of

delphi }

   asm

      mov ax, [bp+04]            { Load physical segm of the calling

proc on call stack }

      mov es, ax

      mov ax, word ptr es:0      { Logical segm stored in 0th position

of physical seg }

      mov progSeg, ax            { Logical, not physical segm used in

Find|Error menu item }

      mov ax, [bp+02]

      mov progOfs, ax            { Physical ofs is used by find|error,

no translation needed }

   end;

   {$ifndef _NDEBUG} { Are we allowed to assert? }

   if (not assertedCond) then begin

      { construct msg\nat location ssss:oooo using the logical address

}

      StrPCopy(msgOut, msgStr);

      tmpStr := chr(10)+'at location

'+IntToHex(progSeg,4)+':'+IntToHex(progOfs,4);

      StrPCopy(hexStr, tmpStr);

      StrCat(msgOut, hexStr);

      {$ifdef WINDOWS}

         MessageBox(0, msgOut, 'Assert Failed',

MB_ICONSTOP+MB_SYSTEMMODAL+MB_OK);

      {$else}

         WriteLn('Assert Failed', msgOut);

      {$endif}

      { Now, terminate the program because of assertion problem }

      halt;

   end;

   {$endif}

end;


DUPLICATING THE ATAN2 FUNCTION IN DELPHI

#2050.TIP	From Nathan Dreon E-Mail: ndreon@osf1.gmu.edu

function sgn (a : real) : real;

begin

  if a < 0  then  sgn := -1;

            else  sgn :=  1;

end;

function atan2 (y, x : real) : real;

begin

  if x > 0       then  atan2 := arctan (y/x)

  else if x < 0  then  atan2 := arctan (y/x) + pi

  else                 atan2 := pi/2 * sgn (y);

end;

{

I did this a while ago when moving from FORTRAN to Pascal.

I think I tested it way back then but my memory is fading

good luck.

}

Nathan

-------------------------------------------------------------------------------

From: Terje Mathisen <Terje.Mathisen@hda.hydro.com>

Subject: Re: How to duplicate C function ATAN2 in Delphi?

Date: 18 May 1995 19:25:10 GMT

I think you should seriously consider using the FPATAN instruction for this!

This x87 opcode implements an IEEE-compliant ATAN2() function, with full extended

precision, and the hardware will handle all the special cases for you.

If you have numeric exceptions enabled, and input bogus values, the x87 chip will

raise the appropriate signal, without the need for upfront testing of parameters.

A BP/TP/Delphi-compatible version would look like this:

Function atan2(y : extended; x : extended): Extended;

Assembler;

asm

  fld [y]

  fld [x]

  fpatan

end;

Total execution time is less than 200 cycles on a Pentium, with less than 1 ulp

maximum error, unless you have a Pentium with the FDIV bug, where it could fail

almost anywhere after the first 15-20 OK bits!  :-)

The library function ArcTan(x) is implemented as fpatan(1.0,x), as long as you

compile with IEEE reals {$N+} set.

Terje

--

-Terje Mathisen (include std disclaimer) <Terje.Mathisen@hda.hydro.com>

"almost all programming can be viewed as an exercise in caching"

-------------------------------------------------------------------------------

This is a potential problem as the win87em.dll or the sw

lib does not work with this so the sw will fail on all non

CoP equipped boxes.

--

Name:        Dr Jon Jenkins

Internet:    jenkinsj@ozy.dec.com


GETTING DIMENSIONS FROM .AVI FILES

#2051.TIP	From Hans Hill E-Mail: hans@attitude.DIALix.oz.au

If you have the Video for Windows Development Kit all the info is in there, But

apparently there is a struct at the start of the .avi file.

Look up MainAVIHeader in the vfwdk help file for more, but here is

the structure -

typedef struct {

        DWORD   dwMicroSecPerFrame;

        DWORD   dwMaxBytesPerSec;

        DWORD   dwPaddingGranularity;

        DWORD   dwFlags;

        DWORD   dwTotalFrames;

        DWORD   dwInitialFrames;

        DWORD   dwStreams;

        DWORD   dwSuggestedBufferSize;

        DWORD   dwWidth;

        DWORD   dwHeight;

        DWORD   dwReserved[4];

        } MainAVIHeader;

I've no idea what MS charge for the vfwdk, but I know its

available when you purchase a Video Blaster Card, and its also

include on the CD that comes with 'Visual Basic MultiMedia'(from

the Coriolis Book Group)


USING CANVAS IN USER-DEFINED COMPONENTS

#2052.TIP	From The Nomad E-Mail: tnomad@digital.net

Suggestion for how to use Canvas in a homegrown component:

TScrollingPaintBox = class(TScrollingWinControl)

  private

    FCanvas: TCanvas;

  public

    constructor Create(aOwner:TComponent); override;

    destructor Destroy; override;

    property Canvas: TCanvas read FCanvas;

end;

constructor TScrollingPaintBox.Create(AOwner: TComponent);

begin

  inherited Create(AOwner);

  FCanvas := TControlCanvas.Create;

  TControlCanvas(FCanvas).Control := Self;

end;

destructor TScrollingPaintBox.Destroy;

begin

  FCanvas.Free;

  inherited Destroy;

end;

A TControlCanvas is important because it creates a DC that belongs to the

HWND of the control.  Also, override is important on your constructor

and destructor to insure that they are actually called.


DETERMINING CD TRACK WITH TMEDIAPLAYER

#2053.TIP	From Mark Barr E-Mail: GSST97B@prodigy.com

{

  Create a timer and put this code in the OnTimer event:

}

var Trk, Min, Sec: Word;

begin

   with MediaPlayer1 do

   begin

      Trk:= MCI_TMSF_TRACK(Position);

      Min:=MCI_TMSF_MINUTE(Position);

      Sec:=MCI_TMSF_SECOND(Position);

      Label1.Caption:=Format('%.2d',[Trk]);

      Label2.Caption:=Format('%.2d:%.2d',[Min,Sec]);

   end;

end;

{

Add MMSystem to the uses clause in Unit1

This will show current track and time.

}


ACCESSING OTHER COMPONENTS FROM A BASE COMPONENT

#2054.TIP	From Mark Johnson E-Mail: keeper@mindspring.com

>How do I access other components in my application from within

>[my Base] component?

The Components[] list property exists in all descendants of TComponent

and is used to store references to any owned components.  When one

calls "mycomponent := TSomeComponent.Create(aComponent)", mycomponent

is placed in aComponent's Components[] list.  In most cases, the form

is specified as a component's owner in the Create method, in which case

the component is placed in the form's Components[] list.

The FindComponent() method (mentioned elsewhere) only searches the current

component's Components[] list.  If the object you want to find is owned

by a different component, you will have to scan the other component's

list.

Depending on how you create your Base and other components, you may have

to implement a recursive search algorithm that starts at the top of the

ownership tree (probably with the form), and then descends into the tree,

searching the Components[] list of each component it finds until the desired

object is reached.

A nice alternative is just to always specify your Base component as the

owner of all your other sub-components when you create them.  Then your

search of the Base component's Components[] list should work.


COLOR TO STRING CONVERSION FUNCTIONS

#2055.TIP	From The Nomad E-Mail: tnomad@digital.net

The GraphicsUnit has two useful functions: StringToColor and ColorToString.

StringToColor will receive one of the valid 37 colors (such as clWhite) or a

number (as a string) representing the color and return a TColor for it.

ColorToString will do the reverse.


DETECTING A PENTIUM PROCESSOR

#2056.TIP	From Ray Lischner E-Mail: lisch@tempest-sw.com

{

Here is a Delphi unit to detect the CPU type, modified from Intel's

code. Use should be fairly obvious.  If not, send me email, and I can

send you an example program.  Because Delphi's assembler is 16-bit,

the code looks a little wierd.  Try using a 32-bit disassembler to see

the 32-bit instructions (or read the comments).

}

unit CpuId;

{ This code comes from Intel, and has been modified for Delphi's

  inline assembler.  Since Intel made the original code freely

  available, I am making my changes freely available.

  Share and enjoy!

  Ray Lischner

  Tempest Software

  6/18/95

}

interface

type

  { All the types currently known.  As new types are created,

    add suitable names, and extend the case statement in

    CpuTypeString.

  }

  TCpuType = (cpu8086, cpu80286, cpu386, cpu486, cpuPentium);

{ Return the type of the current CPU }

function CpuType: TCpuType;

{ Return the type as a short string }

function CpuTypeString: String;

implementation

uses SysUtils;

function CpuType: TCpuType; assembler;

asm

  push DS

{ First check for an 8086 CPU }

{ Bits 12-15 of the FLAGS register are always set on the }

{ 8086 processor. }

  pushf	       { save EFLAGS }

  pop	bx	          { store EFLAGS in BX }

  mov	ax,0fffh	    { clear bits 12-15 }

  and	ax,bx	       { in EFLAGS }

  push	ax	       { store new EFLAGS value on stack }

  popf	 	       { replace current EFLAGS value }

  pushf	       { set new EFLAGS }

  pop	ax	          { store new EFLAGS in AX }

  and	ax,0f000h	    { if bits 12-15 are set, then CPU }

  cmp	ax,0f000h	    { is an 8086/8088 }

  mov 	ax, cpu8086     { turn on 8086/8088 flag }

  je	@@End_CpuType

  { 80286 CPU check }

  { Bits 12-15 of the FLAGS register are always clear on the }

  { 80286 processor. }

  or	bx,0f000h	    { try to set bits 12-15 }

  push 	bx

  popf

  pushf

  pop	ax

  and	ax,0f000h	      { if bits 12-15 are cleared, CPU=80286 }

  mov 	ax, cpu80286      { turn on 80286 flag }

  jz	@@End_CpuType

  { To test for 386 or better, we need to use 32 bit instructions,

    but the 16-bit Delphi assembler does not recognize the 32 bit opcodes

    or operands.  Instead, use the 66H operand size prefix to change

    each instruction to its 32-bit equivalent. For 32-bit immediate

    operands, we also need to store the high word of the operand immediately

    following the instruction.  The 32-bit instruction is shown in a comment

    after the 66H instruction.

  }

  { i386 CPU check }

  { The AC bit, bit #18, is a new bit introduced in the EFLAGS }

  { register on the i486 DX CPU to generate alignment faults. }

  { This bit can not be set on the i386 CPU. }

  db 66h                    { pushfd }

  pushf

  db 66h                    { pop eax }

  pop	ax	                { get original EFLAGS }

  db 66h                    { mov ecx, eax }

  mov	cx,ax	             { save original EFLAGS }

  db 66h                    { xor eax,40000h }

  xor	ax,0h	                { flip AC bit in EFLAGS }

  dw 0004h

  db 66h                    { push eax }

  push ax	          { save for EFLAGS }

  db 66h                    { popfd }

  popf	          { copy to EFLAGS }

  db 66h                    { pushfd }

  pushf	          { push EFLAGS }

  db 66h                    { pop eax }

  pop	ax	                { get new EFLAGS value }

  db 66h                    { xor eax,ecx }

  xor	ax,cx	             { can't toggle AC bit, CPU=Intel386 }

  mov ax, cpu386            { turn on 386 flag }

  je @@End_CpuType

{ i486 DX CPU / i487 SX MCP and i486 SX CPU checking }

{ Checking for ability to set/clear ID flag (Bit 21) in EFLAGS }

{ which indicates the presence of a processor }

{ with the ability to use the CPUID instruction. }

  db 66h                    { pushfd }

  pushf	          { push original EFLAGS }

  db 66h                    { pop eax }

  pop	ax	                { get original EFLAGS in eax }

  db 66h                    { mov ecx, eax }

  mov	cx,ax	             { save original EFLAGS in ecx }

  db 66h                    { xor eax,200000h }

  xor	ax,0h	                { flip ID bit in EFLAGS }

  dw 0020h

  db 66h                    { push eax }

  push ax	          { save for EFLAGS }

  db 66h                    { popfd }

  popf	          { copy to EFLAGS }

  db 66h                    { pushfd }

  pushf                     { push EFLAGS }

  db 66h                    { pop eax }

  pop	ax	                { get new EFLAGS value }

  db 66h                    { xor eax, ecx }

  xor ax, cx

  mov ax, cpu486            { turn on i486 flag }

  je @@End_CpuType	       { if ID bit cannot be changed, CPU=486

}

  { without CPUID instruction functionality }

{ Execute CPUID instruction to determine vendor, family, }

{ model and stepping.  The use of the CPUID instruction used }

{ in this program can be used for B0 and later steppings }

{ of the P5 processor. }

   db 66h                  { mov eax, 1 }

   mov ax, 1	      { set up for CPUID instruction }

   dw 0

   db 66h                  { cpuid }

db	0Fh	              { Hardcoded opcode for CPUID instruction }

db	0a2h

   db 66h                  { and eax, 0F00H }

and ax, 0F00H	         { mask everything but family }

   dw 0

   db 66h                  { shr eax, 8 }

shr ax, 8               { shift the cpu type down to the low byte }

   sub ax, 1               { subtract 1 to map to TCpuType }

@@End_CpuType:

   pop ds

end;

function CpuTypeString: String;

var

  kind: TCpuType;

begin

  kind := CpuType;

  case kind of

  cpu8086:

    Result := '8086';

  cpu80286:

    Result := '80286';

  cpu386:

    Result := '386';

  cpu486:

    Result := '486';

  cpuPentium:

    Result := 'Pentium';

  else

    { Try to be flexible for future cpu types, e.g., P6. }

    Result := Format('P%d', [Ord(kind)]);

  end;

end;

end.


DISPLAYING IMAGES WITH DBGRID

#2057.TIP	From Bill Raike E-Mail: sraike@iconz.co.nz

{

// DBPICGRD.PAS (C) 1995 W. Raike

//              ALL RIGHTS RESERVED.

//

//    DESCRIPTION:

//      Data-aware grid that can display graphic fields.

//    REVISION HISTORY:

//      15/04/95  Created.    W. Raike

}

unit DBPicGrd;

interface

uses

  DBGrids, DB, DBTables, Grids, WinTypes, Classes, Graphics;

type

  TDBPicGrid = class(TDBGrid)

  protected

    procedure DrawDataCell(const Rect: TRect;

      Field: TField; State: TGridDrawState); override;

  public

    constructor Create(AOwner : TComponent); override;

  published

    property DefaultDrawing default False;

  end;

procedure Register;

implementation

constructor TDBPicGrid.Create(AOwner : TComponent);

begin

  inherited Create(AOwner);

  DefaultDrawing := False;

end;

procedure TDBPicGrid.DrawDataCell(const Rect: TRect; Field: TField;

State: TGridDrawState);

var

  bmp : TBitmap;

begin

  with Canvas do

  begin

    FillRect(Rect);

    if Field is TGraphicField then

        try

          bmp := TBitmap.Create;

          bmp.Assign(Field);

          Draw(Rect.Left, Rect.Top, bmp);

        finally

          bmp.Free;

        end

    else

      TextOut(Rect.Left, Rect.Top, Field.Text);

  end;

end;

procedure Register;

begin

  RegisterComponents('Custom', [TDBPicGrid]);

end;

end.


EXTENDING DBGRID

#2058.TIP	From Brian Murray E-Mail: murray@uansv3.Vanderbilt.Edu

{

Here's a TDBGrid derivative that exposes the Col, Row and Canvas properties

as well as the CellRect method.  This is extremely useful if you would like

to, for example, pop a dropdown list over a cell when the user enters.

}

unit VUBComps;

interface

uses

  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,

  Forms, Dialogs, Grids, DBGrids, DB, Menus;

type

  TDBGridVUB = class(TDBGrid)

  private

    { Private declarations }

  protected

    { Protected declarations }

  public

    property Canvas;

    function CellRect(ACol, ARow: Longint): TRect;

    property Col;

    property Row;

procedure Register;

implementation

procedure Register;

begin

  RegisterComponents('VUBudget', [TDBGridVUB]);

end;

function TDBGridVUB.CellRect(ACol, ARow: Longint): TRect;

begin

  Result := inherited CellRect(ACol, ARow);

end;

end.


DELAY PROCEDURE

#2059.TIP	From Nivaldo Fernandes E-Mail: n.fernandes@conservation.org

procedure TForm1.Delay(msecs:integer);

var

   FirstTickCount:longint;

begin

     FirstTickCount:=GetTickCount;

     repeat

           Application.ProcessMessages; {allowing access to other

                                         controls, etc.}

     until ((GetTickCount-FirstTickCount) >= Longint(msecs));

end;


ACCESSING DOS ENVIRONMENT DATA FROM DELPHI

#2060.TIP	From Claude Pellerin E-Mail: pclaude@iccu6.ipswichcity.qld.gov.au

{

The little Project attached shows how to list all the Environment

variables quite simply.

}

program Getenv;

uses WinCrt,WinProcs;

var

 ptr: PChar;

 Done: BOOLEAN;

begin

 ptr := GetDOSEnvironment;

 Done := FALSE;

 WHILE NOT Done DO

 BEGIN

  IF ptr^ = #0 THEN

  BEGIN

   Writeln;

   INC(ptr);

   IF ptr^ = #0 THEN Done := TRUE

   ELSE Write(ptr^);

  END

  ELSE Write(ptr^);

  INC(ptr);

 END;

end.


CREATING A RESIZABLE (ELASTIC) PANEL

#2061.TIP	From Dion Kurczek E-Mail: dionkk@ix.netcom.com

{

  Here's the source code for a resizable panel.  Give the panel an align

  property of alClient, throw some controls on it, and watch them resize

  at run time when you resize the form.  There is some code that prohibits

  resizing during design time, but this can be taken out.  This may not be

  perfect, because I threw it together in a few minutes, but it's worked

  for me so far.

}

unit Elastic;

interface

uses

  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,

  Forms, Dialogs, ExtCtrls;

type

  TElasticPanel = class( TPanel )

  private

     FHorz, FVert: boolean;

     nOldWidth, nOldHeight: integer;

     bResized: boolean;

  protected

     procedure WMSize( var message: TWMSize ); message WM_SIZE;

  public

     nCount: integer;

     constructor Create( AOwner: TComponent ); override;

  published

     property ElasticHorizontal: boolean read FHorz write FHorz default TRUE;

     property ElasticVertical: boolean read FVert write FVert default TRUE;

  end;

procedure Register;

implementation

constructor TElasticPanel.Create( AOwner: TComponent );

begin

  inherited Create( AOwner );

  FHorz := TRUE;

  FVert := TRUE;

  nOldWidth := Width;

  nOldHeight := Height;

  bResized := FALSE;

end;

procedure TElasticPanel.WMSize( var message: TWMSize );

var

  bResize: boolean;

  xRatio: real;

  i: integer;

  ctl: TWinControl;

begin

  Inc( nCount );

  if Align = alNone then

     bResize := TRUE

  else

     bResize := bResized;

  if not ( csDesigning in ComponentState ) and bResize then

     begin

        if FHorz then

           begin

              xRatio := Width / nOldWidth;

              for i := 0 to ControlCount - 1 do

                 begin

                    ctl := TWinControl( Controls[i] );

                    ctl.Left := Round( ctl.Left * xRatio );

                    ctl.Width := Round( ctl.Width * xRatio );

                 end;

           end;

        if FVert then

           begin

              xRatio := Height / nOldHeight;

              for i := 0 to ControlCount - 1 do

                 begin

                    ctl := TWinControl( Controls[i] );

                    ctl.Top := Round( ctl.Top * xRatio );

                    ctl.Height := Round( ctl.Height * xRatio );

                 end;

           end;

     end

  else

     begin

        nOldWidth := Width;

        nOldHeight := Height;

     end;

  bResized := TRUE;

  nOldWidth := Width;

  nOldHeight := Height;

end;

procedure Register;

begin

  RegisterComponents('Additional', [TElasticPanel]);

end;

end.


TRAPPING WM_ENDSESSION MESSAGE IN DELPHI

#2062.TIP	From Hallvard Vassbotn E-Mail: hallvard@falcon.no

The problem seems to be that when you close down Windows, it will first

send a WM_QueryEndSession message to all running top-level windows. This

is handled and processed correctly by the TForm object in VCL.

Then assuming that all applications indicated that it was ok to close down,

Windows will send WM_EndSession messages to all windows. This message is

not handled by VCL. The application is simply brought down with a bang.

No windows are closed, no destructor called and no exit procedures called.

The solution is to handle the WM_EndSession message yourself. There are

several ways of handling messages in Delphi, but the only reliable way

of handling the WM_ENDSESSION is to use the HookWindow method of

Application.

In the message handler, check to see if the message is a WM_ENDSESSION.

If so, we should close down the application. We could have called the

Close method of the main window, but the Windows API documentation states

that the system might go down anytime after return from the WM_ENDSESSION,

and a posted WM_QUIT message might never arrive to the application.

The solution is to simply call Halt instead. This will call all registred

exit procedures, including the ones in Controls and DB units. These will

free the application and screen objects and take the BDE down correctly.

A simple example follows:

unit Tst2u;

interface

uses

  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,

  Forms, Dialogs, Grids, DBGrids, DB, DBTables;

type

  TForm1 = class(TForm)

    DataSource1: TDataSource;

    Table1: TTable;

    DBGrid1: TDBGrid;

    procedure FormCreate(Sender: TObject);

  private

    { Private declarations }

    function HookProc(var Message: TMessage): boolean;

  public

    { Public declarations }

  end;

var

  Form1: TForm1;

implementation

{$R *.DFM}

const

  FlagFileName = 'C:\Flag.Fil';

procedure CreateFlagFile;

var

  F: System.Text;

begin

  System.Assign(F, FlagFileName);

  System.Rewrite(F);

  Writeln(F, 'This is a dummy flag file');

  System.Close(F);

end;

procedure KillFlagFile;

var

  F: File;

begin

  System.Assign(F, FlagFileName);

  System.Erase(F);

end;

procedure MyExitProc; far;

begin

  KillFlagFile;

end;

procedure TForm1.FormCreate(Sender: TObject);

begin

  Application.HookMainWindow(HookProc);

end;

function TForm1.HookProc(var Message: TMessage): boolean;

begin

  Result := false;

  if Message.Msg = WM_EndSession then

  begin

    if WordBool(Message.wParam) then

    begin

      { Windows is closing down - clean up!! }

      { This should execute all ExitProcs, close windows and call destructors... }

       Halt; { This works! }

      { This should close things down properly,

        but do we have enough time to handle any posted messages before Windows

        is already down??  This will result in a PostQuitMessage that might

        never arrive!}

{      Close;} { This doesn't always work - avoid it }

    end;

  end;

end;

initialization

  CreateFlagFile;

  AddExitProc(MyExitProc);

end.

This unit demonstrates that the exit procedures are called when closing

the app normally and when closing down Windows and using HookMainWindow.

Without the HookMainWindow call, the exit proc will not be called. This

is specially important for DB applications. Without the Halt, LCK files

will not be deleted, buffers might not be flushed, changes posted and

so on.


RESTARTING WINDOWS

#2063.TIP	From J. Stephen R. Silber E-Mail: jsrs@cyberspace.com

There are two documented functions in the Windows API for restarting

Windows: ExitWindows(), and ExitWindowsExec().  (See the Windows API help

for details on both.) A common misconception is that the Program Manager DDE

macro call "[Reload()]" is for restarting Windows; it is not!

The call ExitWindows( 0, EW_RESTARTWINDOWS ) is _supposed_ to shut down

Windows, then bring it back up.  I've had no luck, though, from inside a

Delphi app.  It just shuts down Windows and gives me a DOS prompt.

ExitWindowsExec was built so that you could shut down Windows, execute a DOS

app (to replace Windows-critical DLL's, for example), and then bring Windows

hack up.  I have discovered that you simply need to pass a bad executable

name, and ExitWindowsExec performs exactly as ExitWindows was supposed to!

For example, the last few lines of an installation application may be:

        if (MessageDlg( 'The installation was successful!  You must now ' +

                       'restart Windows.  Do this now?', mtInformation,

                       [mbYes, mbNo], 0) = mrYes) then begin

           ExitWindowsExec( BOGUS_EXE, Nil );

        end;

where BOGUS_EXE is declared something like

        const

           BOGUS_EXE = 'zyxwvuts.exe';


READING AND WRITING DATA TO/FROM FILES

#2064.TIP	From Michael Vincze E-Mail: mav@dseg.ti.com

{

  The following example shows how to write and read data to

  and from a file.  It is intended merely as a starting

  point for those that are struggling to get started with

  file related IO.  Please read the documentation on each

  object for more information.  Some very minimal exception

  handling is thrown in and by no means constitutes a

  robust solution

  In order to setup the program, place a TMemo component on

  a form with a Write captioned and a Read captioned button.

  Run the program, place some lines in the "memo", then

  press on Write.  Clear the "memo", and press on Read.

}

  procedure TForm1.BtnWriteClick(Sender: TObject);

  { by:  Michael Vincze

  }

  var

    FileStream: TFileStream;

    Writer    : TWriter;

    I         : Integer;

  begin

  FileStream := TFileStream.Create ('c:\delphi\projects\delta40\fileio\stream.txt',

    fmCreate or fmOpenWrite or fmShareDenyNone);

  Writer := TWriter.Create (FileStream, $ff);

  Writer.WriteListBegin;

  for I := 0 to Memo1.Lines.Count - 1 do Writer.WriteString (Memo1.Lines[I]);

  Writer.WriteListEnd;

  Writer.Destroy;

  FileStream.Destroy;

  end;

  procedure TForm1.BtnReadClick(Sender: TObject);

  { by:  Michael Vincze

  }

  var

    FileStream: TFileStream;

    Reader    : TReader;

  begin

  { try opening a non existent file

  }

  try

    FileStream := TFileStream.Create ('c:\delphi\projects\delta40\fileio\bogus.txt',

      fmOpenRead);

  except

    ; { no need to Destroy since the Create failed  }

    end;

  FileStream := TFileStream.Create ('c:\delphi\projects\delta40\fileio\stream.txt',

    fmOpenRead);

  Reader := TReader.Create (FileStream, $ff);

  Reader.ReadListBegin;

  Memo1.Lines.Clear;

  while not Reader.EndOfList do Memo1.Lines.Add (Reader.ReadString);

  Reader.ReadListEnd;

  Reader.Destroy;

  FileStream.Destroy;

  end;


TRIMMING SPACES FROM STRINGS

#2065.TIP	From Dr. Bob E-Mail: 100434.2072@compuserve.com

  unit TrimStr;

{

  NOTE: The compiler must be in the default mode for boolean evaluation, i.e.,

  short-circuiting

}

  interface

  Const

    Space = #$20;

    function LTrim(Str: String): String;

    function RTrim(Str: String): String;

    function Trim(Str: String):  String;

  implementation

    function LTrim(Str: String): String;

    var len: Byte absolute Str;

        i: Integer;

    begin

      i := 1;

      while (i <= len) and (Str[i] = Space) do Inc(i);

      LTrim := Copy(Str,i,len-i+1)

    end {LTrim};

    function RTrim(Str: String): String;

    var len: Byte absolute Str;

    begin

      while (Str[len] = Space) do Dec(len);

      RTrim := Str

    end {RTrim};

    function Trim(Str: String): String;

    begin

      Trim := LTrim(RTrim(Str))

    end {Trim};

  end.

Groetjes,

          Dr. Bob

-------------------------------------------------------------------------------

From: pierre@panpan.synapse.net (Pierre Tourigny)

Subject: Re: Any simple way to trim spaces from a string? (... Delphi related ...)

Date: Fri, 31 Mar 1995 09:29:26 LOCAL

The ltrim function doesn't work correctly when the string is all spaces.

Replace i < len with i <= len. This works because copy returns an empty

string when i > len.

(N.B.: The compiler must be in the default mode for boolean evaluation, i.e.,

short-circuiting).


CONTROLLING FORM MAXIMIZATION

#2066.TIP	From Ben Licht E-Mail: benl@panix.com

I just wrote out a simple little program that will allow you to control the size

of a form when it is maximized.  It does this in such a way as to remove the

flickering that you see if you've been adjusting the size via the resize event.

Basically, this code traps the wm_getminmaxinfo message. To use this style form

instead of the Delphi standard, simply compile the following text pascal file

into a DCU. Then replace occurences of TForm with TMaxForm and add (if you

called the pascal file maxform.pas) maxform to your uses clause.  Here now is

the short program:

unit Maxform;

interface

uses

  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,

  Forms, Dialogs;

type

  TMaxForm = class(TForm)

  private

    { Private declarations }

    fmh, fmw, fml, fmt : word;

    procedure mymax(var m: TWMGETMINMAXINFO);

              message wm_getminmaxinfo;

  published

    property maxheight : word read mh write mh;

    property maxwidth  : word read mw write mw;

    property maxleft   : word read ml write ml;

    property maxtop    : word read mt write mt;

    constructor create(AOwner : TComponent); override;

  end;

implementation

procedure TMaxForm.mymax(var m : TWMGETMINMAXINFO);

begin

  m.minmaxinfo^.ptmaxsize.x := fmw;

  m.minmaxinfo^.ptmaxsize.y := fmh;

  m.minmaxinfo^.ptmaxposition.x := fml;

  m.minmaxinfo^.ptmaxposition.y := fmt;

end;

constructor TMaxForm.create(Aowner : TComponent);

begin

  fmw := screen.width;

  fmh := screen.height;

  fmt := 0;

  fml := 0;

  inherited create(aowner);

end;

end.


REMOVING TITLE BAR FROM MDI CHILD FORM

#2067.TIP	From The Nomad E-Mail: tnomad@digital.net

{

  We were able to kill the title bar of an MDI child by doing the following:

}

type

  TForm2 = class(TForm)

{ other stuff above }

procedure CreateParams(var Params: TCreateParams); override;

{ other stuff below }

  end;

procedure TForm2.CreateParams(var Params: TCreateParams);

begin

  inherited CreateParams(Params);

  Params.Style := Params.Style and not WS_OVERLAPPEDWINDOW or WS_BORDER

end;


DETERMINING CURSOR POSITION WITHIN EDIT FIELD

#2068.TIP	From XSF E-Mail: xsf@aol.com

To determine position of cursor in edit field try this:

Lpos := SendMessage(memo1.Handle,EM_LINEFROMCHAR,Memo1.SelStart,0);

Cpos := SendMessage(memo1.Handle,EM_LINEINDEX,Lpos,0);

LineLength := SendMessage(memo1.handle, EM_LINELENGTH, Cpos, 0);

CPos := Memo1.SelStart-CPos;

Lpos = line position

Cpos = Cposition

LineLength = number of characters in current line


ASSIGNING ONCLICK EVENTS FOR MENU ITEMS CREATED AT RUN-TIME

#2069.TIP	From The Nomad E-Mail: tnomad@digital.net

Since the OnClick method is a property, when you dynamically create the

menu item, also assign the name of on OnClick handler:

theMenuitem.OnClick := TheOnClickHandler;

Then, in the OnClick handler, you cast the sender into a TMenuItem and

read the name:

procedure theform.TheOnClickHandler(Sender: TObject);

var

fName: String;

begin

fName := TMenuItem(Sender).name;

...

end;


DRAWING TO A METAFILE

#2070.TIP	From Rene Post E-Mail: renep@xs4all.nl

unit Metaform;

interface

uses

  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,

  Forms, Dialogs, StdCtrls, Buttons, ExtCtrls;

type

  TForm1 = class(TForm)

    Panel1: TPanel;

    BitBtn1: TBitBtn;

    Image1: TImage;

    procedure BitBtn1Click(Sender: TObject);

  private

    { Private declarations }

  public

    { Public declarations }

  end;

var

  Form1: TForm1;

implementation

{$R *.DFM}

type

  TMetafileCanvas = class(TCanvas)

  private

    FClipboardHandle: THandle;

    FMetafileHandle: HMetafile;

    FRect: TRect;

  protected

    procedure CreateHandle; override;

    function GetMetafileHandle: HMetafile;

  public

    constructor Create;

    destructor Destroy; override;

    property Rect: TRect read FRect write FRect;

    property MetafileHandle: HMetafile read GetMetafileHandle;

  end;

constructor TMetafileCanvas.Create;

begin

  inherited Create;

  FClipboardHandle := GlobalAlloc(

    GMEM_SHARE or GMEM_ZEROINIT, SizeOf(TMetafilePict));

end;

destructor TMetafileCanvas.Destroy;

begin

  DeleteMetafile(CloseMetafile(Handle));

  if Bool(FClipboardHandle) then GlobalFree(FClipboardHandle);

  if Bool(FMetafileHandle) then DeleteMetafile(FMetafileHandle);

  inherited Destroy;

end;

procedure TMetafileCanvas.CreateHandle;

var

  MetafileDC: HDC;

begin

  { Create a metafile DC in memory }

  MetafileDC := CreateMetaFile(nil);

  if Bool(MetafileDC) then

  begin

    { Map the top,left corner of the displayed rectangle to the

top,left of the

      device context. Leave a border of 10 logical units around the

picture. }

    with FRect do SetWindowOrg(MetafileDC, Left - 10, Top - 10);

    { Set the extent of the picture with a border of 10 logical units.

}

    with FRect do SetWindowExt(MetafileDC, Right - Left + 20, Bottom -

Top + 20);

    { Play any valid metafile contents to it. }

    if Bool(FMetafileHandle) then

    begin

      PlayMetafile(MetafileDC, FMetafileHandle);

    end;

  end;

  Handle := MetafileDC;

end;

function TMetafileCanvas.GetMetafileHandle: HMetafile;

var

  MetafilePict: PMetafilePict;

  IC: HDC;

  ExtRect: TRect;

begin

  if Bool(FMetafileHandle) then DeleteMetafile(FMetafileHandle);

  FMetafileHandle := CloseMetafile(Handle);

  Handle := 0;

  { Prepair metafile for clipboard display. }

  MetafilePict := GlobalLock(FClipboardHandle);

  MetafilePict^.mm := mm_AnIsoTropic;

  IC := CreateIC('DISPLAY', nil, nil, nil);

  SetMapMode(IC, mm_HiMetric);

  ExtRect := FRect;

  DPtoLP(IC, ExtRect, 2);

  DeleteDC(IC);

  MetafilePict^.xExt := ExtRect.Right - ExtRect.Left;

  MetafilePict^.yExt := ExtRect.Top - ExtRect.Bottom;

  MetafilePict^.HMF :=  FMetafileHandle;

  GlobalUnlock(FClipboardHandle);

  { I'm giving you this handle, but please do NOT eat it. }

  Result := FClipboardHandle;

end;

procedure TForm1.BitBtn1Click(Sender: TObject);

var

  MetafileCanvas : TMetafileCanvas;

begin

  MetafileCanvas := TMetafileCanvas.Create;

  MetafileCanvas.Rect := Rect(0,0,500,500);

  MetafileCanvas.Ellipse(10,10,400,400);

  Image1.Picture.Metafile.LoadFromClipboardFormat(

    cf_MetafilePict, MetafileCanvas.MetafileHandle, 0);

  MetafileCanvas.Free;

end;

end.


HOW TO FORM A DDE LINK WITH A NETSCAPE WEB BROWSER

#2071.TIP	From Kerry Podolsky E-Mail: Kerry_Podolsky@alarmnet.com

     unit Netscp1;

     interface

     uses

       SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,

       Forms, Dialogs, StdCtrls, DdeMan;

     type

       TForm1 = class(TForm)

         DdeClientConv1: TDdeClientConv;

         Button1: TButton;

         Button2: TButton;

         Button3: TButton;

         LinkStatus: TEdit;

         Label1: TLabel;

         Label2: TLabel;

         URLName: TEdit;

         procedure Button1Click(Sender: TObject);

         procedure FormCreate(Sender: TObject);

         procedure Button2Click(Sender: TObject);

         procedure Button3Click(Sender: TObject);

       private

         { Private declarations }

       public

         { Public declarations }

       end;

     var

       Form1: TForm1;

       LinkOpened: Integer;

     implementation

     {$R *.DFM}

     procedure TForm1.Button1Click(Sender: TObject);

     begin

       If LinkOpened = 0 Then

       Begin

         DdeClientConv1.SetLink('Netscape', 'WWW_OpenURL');

         If DdeClientConv1.OpenLink Then

         begin

           LinkStatus.Text := 'Netscape Link has been opened';

           LinkOpened := 1;

         end

         else

           LinkStatus.Text := 'Unable to make Netscape Link';

       End;

     end;

     procedure TForm1.FormCreate(Sender: TObject);

     begin

       LinkOpened := 0;

     end;

     procedure TForm1.Button2Click(Sender: TObject);

     begin

       DdeClientConv1.CloseLink;

       LinkOpened := 0;

       LinkStatus.Text := 'Netscape Link has been closed';

     end;

     procedure TForm1.Button3Click(Sender: TObject);

     var

        ItemList: String;

     begin

       If LinkOpened <> 0 Then

       begin

         ItemList := URLName.Text + ',,0xFFFFFFFF,0x3,,,';

         DdeClientConv1.RequestData(ItemList);

       End;

     end;

     end.


PREVENTING MULTIPLE INSTANCES OF SAME APPLICATION

#2072.TIP	From Anders Ohlsson E-Mail: ao@it.kth.se

Put the following at the top of your application (i.e., in the .DPR file):

begin

  if HPrevInst <> 0 then begin

    ActivatePreviousInstance;

    Exit;

  end;

Also include the following unit:

unit PrevInst;

interface

uses WinProcs, WinTypes, SysUtils;

type

  PHWnd = ^HWnd;

function EnumFunc(Wnd : HWnd; TargetWindow : PHWnd): Bool; export;

procedure ActivatePreviousInstance;

implementation

function EnumFunc(Wnd : HWnd; TargetWindow : PHWnd): Bool;

var

  ClassName : array [0..30] of char;

begin

  Result := True;

  if GetWindowWord(Wnd,GWW_HINSTANCE) = HPrevInst then begin

    GetClassName(Wnd,ClassName,30);

    if StrIComp(ClassName,'TApplication') = 0 then begin

      TargetWindow^ := Wnd;

      Result := False;

    end;

  end;

end;

procedure ActivatePreviousInstance;

var

  PrevInstWnd : HWnd;

begin

  PrevInstWnd := 0;

  EnumWindows(@EnumFunc,Longint(@PrevInstWnd));

  if PrevInstWnd <> 0 then

    if IsIconic(PrevInstWnd) then

      ShowWindow(PrevInstWnd,SW_RESTORE)

    else

      BringWindowToTop(PrevInstWnd);

end;

end.


WRITING A SCREEN SAVER IN DELPHI

#2073.TIP	From Thomas W. Wolf E-Mail: twwolf@cacd.rockwell.com

a) In the project file (*.dpr) add '{$D SCRNSAVE <saver name>} after the

uses clause.

b) On the main form, turn off the border and icon controls. In the

activate method set the form left and top to 0, and set the Windowstate

to wsMaximize.

c) In the form create method, set the application.OnMessage to a method

that controls the deactivation of the screen saver. Set the

application.OnIdle method to whatever display method for the saver.

d) In the form create method the command line should be tested for /c and

/s. These are the command line parameters windows uses to define whether

the screensaver should run or configure. (/c is for configuration)

e) Compile the program, and rename the .exe to .scr. Move it to the

windows directory, and it should show up in the control panel.


HOW TO AUTOMATE MEMO OR WINDOW SCROLLING

#2074.TIP	From The Nomad E-Mail: tnomad@digital.net

procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;

  Shift: TShiftState);

begin

  if Key = VK_F8 then

    SendMessage(Memo1.Handle,  { HWND of the Memo Control }

                WM_VSCROLL,    { Windows Message }

                SB_PAGEDOWN,   { Scroll Command }

                0)             { Not Used }

  else if Key = VK_F7 then

    SendMessage(Memo1.Handle,  { HWND of the Memo Control }

                WM_VSCROLL,    { Windows Message }

                SB_PAGEUP,     { Scroll Command }

                0);            { Not Used }

end;


SETTING BOUNDARIES FOR NEWLY CREATED CONTROLS

#2075.TIP	From Mark Johnson E-Mail: keeper@mindspring.com

If you are designing a new Delphi control and you need to catch

or limit changes to Left, Top, Width, or Height, there is one

simple way to do it.  However, I have yet to see the slightest

hint of how to do it in the Delphi documentation (including

the CWG).

The key to catching changes to Left, Top, Width, Height, and

even BoundsRect in Delphi is the SetBounds() method (found

in TControl and all descendants).  SetBounds() is a virtual

function used to set the position and size of a control

all in one easy step.  However, what they do not tell you

in the documentation is that TControl.SetBounds() is called

by TControl's SetLeft(), SetTop(), SetWidth(), and SetHeight()

property access methods every time a value is assigned to

the Left, Top, Width, Height, and BoundsRect properties.

Thus, to catch changes to these properties, simply override

the SetBounds() method, do whatever you need with the new

values, and then pass them on to the inherited SetBounds()

method.

In the following example, I have a control that automatically

updates its X & Y custom properties to refer to the center

of the control whenever Left, Top, Width, Height, or BoundsRect

are changed.  Conversely, Left and Top will be updated whenever

X & Y are changed:

type

  TMyControl = class(TControl)

  private

    FX, FY : integer;

    {property access methods}

    procedure SetX(value : integer);

    procedure SetY(value : integer);

    ...

  public

    procedure SetBounds(aLeft, aTop, aWidth, aHeight : integer); override;

    ...

    property X : integer read FX write SetX;

    property Y : integer read FY write SetY;

  end;

...

procedure TMyControl.SetX(value : integer);

begin

  if FX <> value then

    SetBounds(value - Width div 2, Top, Width, Height);

end;

procedure TMyControl.SetY(value : integer);

begin

  if FY <> value then

    SetBounds(Left, value - Height div 2, Width, Height);

end;

procedure TMyControl.SetBounds(aLeft, aTop, aWidth, aHeight : integer);

begin

  {Go ahead and let SetBounds() do its thing...}

  inherited SetBounds(aLeft, aTop, aWidth, aHeight);

  {Now adjust FX and FY according to our new bounds.}

  FX := Width div 2;

  FY := Height div 2;

end;

Also not mentioned in the documentation is the fact that the

FLeft, FTop, FWidth, and FHeight private fields that TControl

uses to keep track of its bounding rectangle are not updated

in the corresponding SetLeft(), SetTop(), etc. property access

methods.  These variables, in fact, do not get updated anywhere

except in TControl's SetBounds() method (as with FX and FY in

the above example).

So, to limit changes to the bounds of your control, you can

override SetBounds() to check and modify any of the properties

before passing the values on to the inherited SetBounds()

method.

In the following example, I have a control that limits its

width and height to no more than 100 pixels:

type

  TMyControl = class(TControl)

    ...

  public

    procedure SetBounds(aLeft, aTop, aWidth, aHeight : integer); override;

    ...

  end;

...

procedure TMyControl.SetBounds(aLeft, aTop, aWidth, aHeight : integer);

begin

  if aWidth > 100 then

    aWidth  := 100;

  if aHeight > 100 then

    aHeight := 100;

  inherited SetBounds(aLeft, aTop, aWidth, aHeight);

end;


SETTING SYSTEM DATE AND TIME

#2076.TIP	From BORLAND

{

  NOTE: All of these functions are contained in the file WINDOS.PAS,

        which should be in your \DELPHI\SOURCE\RTL70 directory.  In

        order to use any of them, you must therefore put WINDOS in

        the USES clause for the appropriate form.

        These prototypes, as well as the entire contents of WINDOS.PAS,

        are Copyright (c) 1991,92 Borland International.

}

procedure SetDate(Year, Month, Day: Word);

{ SetDate sets the current date in the operating system. Valid  }

{ parameter ranges are: Year 1980-2099, Month 1-12 and Day      }

{ 1-31. If the date is not valid, the function call is ignored. }

procedure SetTime(Hour, Minute, Second, Sec100: Word);

{ SetTime sets the time in the operating system. Valid          }

{ parameter ranges are: Hour 0-23, Minute 0-59, Second 0-59 and }

{ Sec100 (hundredths of seconds) 0-99. If the time is not       }

{ valid, the function call is ignored.                          }


COPYING FILES USING LZEXPAND

#2077.TIP	From J. Stephen R. Silber E-Mail: jsrs@cyberspace.com

For an installation program, I needed to be able to copy files into certain

directories.  I found myself needing a way to copy a file of any size, without

having to blow the stack on a large file buffer.

To this end, I explored the LZExpand unit and developed the function shown

below.  Note that this function expects to find the source file as a

standard DOS LZ-compressed file.  (These are the files you find on DOS and

Windows installation disks that look like "SETUP.EX_".)  You need to use the

DOS utility COMPRESS to first convert the source file to a COMPRESSed file.

Unfortunately, Delphi does not come with COMPRESS!  You'll need to grab it

from another compiler package (like BP or BC++.)

{ CopyFile returns True on a successful copy, False on failure. }

function CopyFile( src, dest: String): Boolean;

   var

      s, d: TOFStruct;

      fs, fd: Integer;

      fnSrc, fnDest: PChar;

   begin

      src:=src + #0;

      dest:=dest + #0;

      fnSrc:=@src[1];   { Trick the Strings into being ASCIIZ }

      fnDest:=@dest[1];

      fs := LZOpenFile( fnSrc, s, OF_READ );    { Get file handles }

      fd := LZOpenFile( fnDest, d, OF_CREATE );

      if LZCopy( fs, fd ) < 0 then      { Here's the magic API call }

         Result:=False

      else

         Result:=True;

      LZClose( fs );    { Make sure to close 'em! }

      LZClose( fd );

   end;


EXPANDING A PATH TO A TOUTLINENODE REFERENCED BY INDEX

#2078.TIP	From Christian Feichtner E-Mail: Christian.Feichtner@jk.uni-linz.ac.at

The purpose I wrote this routine was, that I had an index from a TOutlineNode

(which was the result of search) and wanted to expand a path to the node

without expanding unnecessary trees.

The following routine accepts an index as a parameter and expands the path

to the TOutlineNode with this index.

The routine assumes a TOutline object named Outline.

var

  Outline: TOutline;

procedure TSearchDlg.ExpandPathToFoundItem(const FoundItemIndex: Longint);

{------------------------------------------------------------------------------

 Expands a path to a given item (item is specified by the index number). Only

 the parents needed to get to the specified item will be expanded.

 -----------------------------------------------------------------------------}

var

  ItemIndex:   Longint;

  Found:       Boolean;

  LastCh:      Longint;

  Path:        String;

  ItemText:    String;

  SepPos:      Integer;

  OldSep:      String;

begin

  {Save the old ItemSpearator}

  OldSep:=Outline.ItemSeparator;

  {Set the new ItemSeparator}

  Outline.ItemSeparator:='\';

  {Get the full path to the TOutlineNode and add a '\'. This is done, because it

   simplifies the whole algorithm}

  Path:=Outline.Items[FoundItemIndex].FullPath+'\';

  {As long as the end of the path has not been reached}

  while Length(Path) > 0 do begin

    {Determine the position of the first '\' in the path}

    SepPos:=Pos('\',Path);

    {Isolate the TOutlineNode item}

    ItemText:=Copy(Path,1,SepPos-1);

    {Determine the index of the TOutlineNode}

    ItemIndex:=Outline.GetTextItem(ItemText);

    {Expand it}

    Outline.Items[ItemIndex].Expand;

    {Cut the expanded TOutlineNode from the string}

    Path:=Copy(Path,SepPos+1,Length(Path)-SepPos+1);

  end;

  {Restore original ItemSeparator}

  Outline.ItemSeparator:=OldSep;

end;

DETAILS

Let's assume the full path to the desired item is:

        "My Computer\Hardware\SoundCard\Base Adress"

The first step returns the above path. Then the substring "My Computer" is

isolated. Then the index of the TOutlineNode "My Computer" is determined by

using the "GetTextItem" method. The "Expand" method expands this tree.

Afterwards "My Computer" is cut from the path resulting in the new path

"Hardware\SoundCard\Base Adress".

Then the index of "Hardware" is determined, expanded and again, cut away.

This procedure repeats until there is no path left to expand. Then the path

to the given TOutlineNode will be expanded.


HIDING REPORTSMITH RUN-TIME ENGINE LOGO

#2080.TIP	From Mickey Mall E-Mail: (none)

To squelch the ReportSmith Run-time Engine logo, look for the file RS_RUN.INI,

which should be in your \WINDOWS directory.  Near the bottom of that file you

should find a section entitled [RS_Runtime].  Add the following statement to

that section:

ShowAboutBox=0


Misc/Tips - MakeProcInstance
MakeProcInstance

#501.TIP	From KWolak@mail.cbf.com Tue Dec 12 12:58:45 1995

On 7 Dec 1995, lincoln wrote:

> I can use LoadLibrary()/GetProcAddress() to call a function in a .DLL.

> Is there a similar way that I can call a function in the current application

> based on a string variable that contains the function name?

Yes, if you export the function (just like a DLL) and hav an exports

clause in the dpr, then you can use GetProcAddres as normal (no need to

load library - it is loaded),  the Handle is that returned by

GetCurrentTask, NOT application.handle.

e.g.

@Routine=GetProcAddress(GetCurrentTask,'MyRoutine');

--

Sam Liddicott                  |   Nothing I say is to be attributed as

Campbell Scientific Ltd.       | a company statement or representation.

14-20 Field Street, Shepshed,  *----------------------------------------

Leicestershire,                             Phone: +44 (0) 1509 601141

United Kingdom. LE12 9AL                    Fax:   +44 (0) 1509 601091


Misc/Tips - MakeProcInstance
MakeProcInstance

#502.TIP	From KWolak@mail.cbf.com Tue Dec 12 12:59:30 1995

Sam Liddicott <sam@csluk.demon.co.uk> wrote:

>On 7 Dec 1995, lincoln wrote:

>> I can use LoadLibrary()/GetProcAddress() to call a function in a .DLL.

>> Is there a similar way that I can call a function in the current application

>> based on a string variable that contains the function name?

>Yes, if you export the function (just like a DLL) and hav an exports

>clause in the dpr, then you can use GetProcAddres as normal (no need to

>load library - it is loaded),  the Handle is that returned by

>GetCurrentTask, NOT application.handle.

[snip]

Note that you can also do this with object methods as well, if they

are published (note that no VCL methods AFAIK have published methods,

but you can always create your own).

To do this, use TObject's MethodAddress method:

var

  method: TMethod    { or whatever the method 'type' is }

begin

  method := MyObject.MethodAddress('MyMethod');

  { execute method by casting it to the appropriate method type }

  TMethod(method);

end;

IMHO published methods are one of Delphi's best kept secrets.  I

wonder what Borland has planned for them :-)

brent_bysouth@mindlink.bc.ca


E-Mail

#503.TIP	From KWolak@mail.cbf.com Tue Dec 12 13:03:07 1995

>

> I need a component wich will allow my app to Login, Send, Read,

> and Delete e-mail for MAPI,VIM and MHS. It has to work with MS Mail,

> ccMail and Lotus Notes.  Any suggestions would be appreciated.

> klc

>

No problem there are various Delphi/MAPI Components around. I use MSN and

Compuserve but should be on Web. VIM/Delphi ive seen in Delphi Developer

magazine. Lotus Notes integration is a commerical product tho im not sure

if its actually released yet.

Chris


CALLBACKS in Delphi - Help?

#504.TIP	From KWolak@mail.cbf.com Tue Dec 12 13:03:49 1995

Pete Gupta wrote:

>

> Does Delphi support Function Pointers (Callbacks)?

>

> I have a third party DLL whose API require function pointers to my locally

> declared functions and subroutines.

> Is this possible in Delphi?

> Does anyone have any sample code of doing callbacks in Delphi?

>

> Any help will be highly appreciated!

> thanks,

> -pete

Search help on the @ sign.

You can actually declare a var of type TDataSetNotifyEvent,

e.g.

  tBeforeDelete :  TDataSetNotifyEvent;

To assign the correct proc to an event:

  tbl.BeforeDelete := MyEventHandler;

Hope this helps

Brahm

=========================

=  Brahm van Niekerk    =

=  Elgin Data Systems   =

=  braame@iafrica.com   =

=  P.O. Box 140         =

=  Elgin                =

=  7180                 =

=========================


Knowing when a task closes?

#505.TIP	From KWolak@mail.cbf.com Tue Dec 12 13:09:57 1995

Mayes uk (mike@d-m-g.demon.co.uk) wrote:

: In my application I start several other applications using

: winexec.

: How can I know if one of those other applications is close down?

: A related question: is it possible to read the windows task list?

: Thanks for your help,

: Mike Watson

: --

: Mayes uk

Save the handle you get from WinExec() and the use the Win API

function GetModuleUsage.

   /Johan...!


Which runs faster?

#506.TIP	From: Arjan Lamaker <e.j.j.lamaker@imag.dlo.nl>

Joe Nodeland wrote:

>

> Does anyone know which code runs faster?

>

> procedure TForm1.SpeedButton1MouseDown(Sender: TObject;

>   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

> begin

>  If Button=mbRight then

>   begin

>    TSpeedButton(Sender).Down:=False;

>    TSpeedButton(Sender).AllowAllUp:=Not(TSpeedButton(Sender).AllowAllUp);

>    If TSpeedButton(Sender).AllowAllUp

>    then TSpeedButton(Sender).GroupIndex:=TSpeedButton(Sender).Tag

>    else TSpeedButton(Sender).GroupIndex:=0;

>   end;

> end;

>

> OR

>

> procedure TForm1.SpeedButton1MouseDown(Sender: TObject;

>   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

> var TheButton:TSpeedButton;

> begin

>  If Button=mbRight then

>   begin

>    TheButton:=TSpeedButton(Sender);

>    TheButton.Down:=False;

>    TheButton.AllowAllUp:=Not TheButton.AllowAllUp;

>    If TheButtonUp.AllowAllUp

>    then TheButton.GroupIndex:=TheButton.Tag

>    else TheButton.GroupIndex:=0;

>   end;

> end;

>

> Thanks in advance.

The two pointers are both on the stack, so there shouldn't be any

difference in code. The typecast is just for the compiler, so both

procedures should execute the same.

The code is hard to read, a nicer way would be:

procedure TForm1.SpeedButton1MouseDown(Sender: TObject;

  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

begin

 If Button=mbRight then

   With Sender As TSpeedButton Do

     Begin

       Down:=False;

       AllowAllUp:=Not AllowAllUp;

       If AllowAllUp Then

         GroupIndex:=Tag

       else

         GroupIndex:=0;

     end;

end;

Borland claims that a With statement is optimized.

-----------------------------------

Arjan Lamaker

IMAG-DLO Wageningen The Netherlands

mail: e.j.j.lamaker@imag.agro.nl

http://huizen.dds.nl/~lamaker/

-----------------------------------


Foward declaring classes???

#507.TIP	From KWolak@mail.cbf.com Tue Dec 12 13:41:13 1995

jsl@data3.com.au (Jeremy Lee) wrote:

>Here's the problem.. i've got two classes, TRMCategory and TRMSkill.

>They're definitions look something like this (extraneous bits removed):

>

>TRMSkill = Class(TObject)

>    private

>    protected

>        { variables }

>        vCategory   : TRMCategory;

>    public

>    end;

>

>TRMCategory = Class(TObject)

>    private

>    protected

>        { variables }

>        vSkill      : TRMSkill;

>    public

>    end;

>

>

>As you can see, each contains a delcared variable of the other class

>type. The above example will not compile because when it's chunking

>through the definition of TRMSkill, TRMCategory has not been defined

>yet. Re-ordering the definitions of course does not help.

>

>I know that I can get away with typecasting a TObject to the relevant

>type in my actual code, but it'd rather not do that. I refer to the

>varaibles an awful lot, you see, and they'll eventually become

>properties as well. I can't expect everyone who uses the classes to know

>that they have to keep typecasting the properties to the correct type

>:-Q

>

>So, how do I do this? How do I forward declare an entire class?

>

Just put:

TRMSkill = class;

at the top of your code.

     -Steve Teixeira

      steixeir@borland.com


Close a help window with delphi code ??

#508.TIP	From KWolak@mail.cbf.com Tue Dec 12 13:45:34 1995

On Tue, 05 Dec 1995 21:23:25 -0100, klausk@login.dknet.dk (Klaus

Kristensen) wrote:

>How do I close a main help window in delphi code?  I have tried with:

>CloseWindow("main");       but it dosn't work.

If the Windows help file was opened by your application, you can make a

call to the Windows API function WinHelp, using as the third parameter

(Command) the value HELP_QUIT. One place to do this in the main form's

OnClose event procedure, as in:

  procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);

  var

    szHelpFile: array [0..255] of Char;

  begin

    StrPCopy(szHelpFile, Application.HelpFile);

    WinHelp(Handle, szHelpFile, HELP_QUIT, 0);

  end;

A well behaved application closes the help file it opens, not leaving it

behind as an orphan window.

**************************************************************************

Steve Koterski

Product Group Manager

Delphi Technical Support

Borland International, Inc.


Is there any equivalent of TPW's Collections in Delphi?

#509.TIP	From KWolak@mail.cbf.com Tue Dec 12 13:46:30 1995

andrewg@netspace.net.au (Andrew Gunner) wrote:

>In article <psteinsund-0712951042540001@geom25.awi-bremerhaven.de>, psteinsund@awi-bremerhaven.de (Per Ivar Steinsund) says:

>>

>>The Collections are not found in Delphi, is there any equivalent

>>structures which can be used?

>>

>>Per Ivar Steinsund

>

>Yes try tList.

>In the Delphi super page there is also supposed to

>be code which has all the features of tCollection.

>Pacheco and Teixeira's book also covers this.

>Regards Andrew Gunner

>

>This should be another FAQ.

Hi

Yes, you find objects7.zip on the Delphi Superpage in the freeware

section. It reimplements the objects unit from BP 7 under Delphi with

some extra features.

Best regards

Guy Fink (By kinf permission of Alain Rassel)


What is the function to cause Delphi To yield execution

#511.TIP	From KWolak@mail.cbf.com Tue Dec 12 14:04:42 1995

 >> FOR Ix := 1 TO 5000 DO

 >> BEGIN

 >> Application.ProcessMessages;

 >> . . . Do_Something_Intensive . . .

 >> END;

 Cc> The problem I am having is that this leaves the all of the forms and

 Cc> controls in the calling program active - which can cause problems if

 Cc> the user does something like close the program! Is there an easy way to

 Cc> prvent this kind of thing?

Try this:

   DiasbleTaskWindows(0);

Jeroen


Launching NetScape from Delphi

#513.TIP	From KWolak@mail.cbf.com Tue Dec 12 14:09:51 1995

From time to time, I see people post questions about launching

NetScape from a Delphi application in this news group.  I recently

encountered some difficulty doing it and thought I'd pass along my

findings here.

The basic approach is to use TDdeConv component to send DDE requests

to NetScape.  The trouble begins if NetScape is not already running.

Here is a code snippet of code that works.  CurrentSelection is a

component whose Caption property  has a URL to hand to NetScape for it

to open and display.

  if CurrentSelection.Caption <> '' then begin

    J := 0;

    while (J < 3) do begin

      { Activate Netscape }

      try

        Screen.Cursor := crHourglass;

        DdeClientConv1.SetLink('NETSCAPE','WWW_Activate');

        DDEReturn := nil;

        if DdeClientConv1.OpenLink then begin

          DdeClientConv1.RequestData('0xFFFFFFFF,0x0');

          DDEClientConv1.CloseLink;

          { Open the URL }

          DDEClientConv1.SetLink('NETSCAPE', 'WWW_OpenURL');

          if (not DDEClientConv1.OpenLink) then begin

            Screen.Cursor := crDefault;

            messageDlg('Could not open link', mtError, [mbOk], 0);

            exit;

          end;

          DDEReturn := DDEClientConv1.RequestData(

            '"' +

            CurrentSelection.Caption +

            '",,0xFFFFFFFF,0x1');

          DDEClientConv1.CloseLink;

          J := 4;

        end else begin

          Inc(J);

          if J >= 3 then begin

            Screen.Cursor := crDefault;

            MessageDlg(DdeClientConv1.ServiceApplication +

              ' could not be found.  Try setting Path to NetScape ' +

              'under Options.',mtError,[mbOk],0)

          end else Yield;

        end;

      finally

        Screen.Cursor := crDefault;

      end;

    end;

  end;

The key thing to note in this code is there is a loop with Yield in

it.  The reason for this is as follows:  If NetScape is not already

active, the first time through the loop will cause NetScape to start

loading.  However, NetScape will yield the CPU back to the Delphi app

before it registers itself as a DDE server app, causing the OpenLink

to return false.  The Yield in the code above then yields back to

NetScape so it can continue initializing itself, whereupon it

registers itself as a DDE server, and eventually yields the CPU back

to the Delphi app again.  So on the second pass through the loop, the

OpenLink method returns true and everything rock and rolls from there.

Question for Win95 experts:  Every book that I have looked at that

describes DDE fails to mention this problem of DDE server apps not

registering themselves before yielding the CPU.  For most DDE server

apps, this is not a problem, but it is for NetScape.  In the

preemptive multitasking Win95 environment, this could become a much

more common problem.  Can anyone confirm?


System Menu while Minimized

#514.TIP	From KWolak@mail.cbf.com Tue Dec 12 14:14:06 1995

>>The reason it works and the reason Pete doesn't get his messags is

>>that the application object in VCL manages a hidden window that is

>>the actual main window of the program in Windows' terms. When the

>>app is non-minimized the main form is displayed. When the app is

>>minimized the hidden window of Application is displayed as an icon.

>>The handle property of Application is simply the handle of this

>>window. Changing the system-menu of this window also changes the

>>system-menu of the icon.

>Do you have any hints on how to respond to the user selecting a menu item

>from the system menu while the application is minimized?

>Its easy to implement a message handler for the TForm descendant that

>responds to system messages, but what about TApplication?

>Should I enhance the hook for trapping application level cascade and tile as

>you suggested in the article "Inside TApplication" in the last issue of the

>Delphi Magazine?

>BTW A very good article in a very good magazine!

Thanks, Nikolai!

I haven't tested this myself yet, but yes, I think that is a solution that

would work. By default, TApplication handles the System Menu commands when

the program is minimized. If you add menu items to this menu, it won't

know how to handle these commands.

The solution is to use the HookMainWindow mechanism and handle these

messages yourself. A simple solution would be to simply resend the message

with parameters to the main form. Something like this might work (not

compiled or tested in any way).

function TMyForm.HookProc(var Message: TMessage): boolean;

begin

  Result := false;

  case Message.Msg of

    WM_MyUserCommand1..WM_MyUserCommandn :

      if MainForm <> nil then

      begin

        MainForm.WndProc(Message);

        Result := true;

      end;

  end;

end;

Calling WndProc directly is the same as calling Perform, but we

don't have to unpack and pack the parameters. Using this method you

can concentrate on putting the logic to handle each message in the

mainform code.

Hope this helps.

--

 Hallvard Vassbotn  | Falcon AS (a Reuters company)  | Without programmers,

 hallvard@falcon.no | Stortorget 10,0155 OSLO,Norway | the world would stop!


Can't access Delphi DLL from VB

#515.TIP	From KWolak@mail.cbf.com Wed Dec 13 10:26:15 1995

jan.olav.endrerud (Jan Olav Endrerud) wrote:

>Do You or anyone else know what the problem is ?

["The problem" with returning reals from dll's]

        Yes. I've read explanations a few times, but I didn't pay attention

because I knew how to "fix" it as above, sorry.

>

>Another thing, I would also like to use the Open-array in delphi to

>pass arrays of different size to Delphi, calculate and return an

>answer.

>

>Something like

>Procedure arrmin (a: array of single; var answer: single); export;

>Begin

>       Answer:=Do_something_with_array;

>End;

>

>When i try to call this function from VB, I get a fatal error in

>the delphi DLL. Any suggestions ?

        When (inside a Delphi program) you pass an array to a function that

has an open-array parameter Delphi actually pushes a word indicating the

length of the array first, which the function reads to decide how long the

array is. If you're calling a dll from VB then you have to do this by hand,

so the VB declaration will appear to have one more parameter than the Delphi

function.

        Detail: You put the word giving the length of the array after the

array itself so it gets pushed onto the stack before the array.

        Detail: It's not actually the length of the array, it's the index

of the last element. The best thing is to be certain the VB array is 0-based

since that's how Delphi's going to read the array; then the "length" word is

actually the number of entries minus 1.

        So if you want to call your "arrmin (a: array of single; var answer:

single)" from VB you'd pass the array, then the number of elements in the array

minus 1, then the "answer" variable. I just verified this is how it works if

you're passing an open array from CA-Realizer to the dll; it will be the same

from VB except the syntax is different, I leave the Declare to you.

        (If this doesn't work consider changing the dll function to

arrmin (var a: array of single; var answer: single)

)

--

David Ullrich

Don't you guys find it tedious typing the same thing

after your signature each time you post something?

I know I do, but when in Rome...


Controlling Glyph transparent color on SpeedButton

#516.TIP	From KWolak@mail.cbf.com Wed Dec 13 10:34:10 1995

Mauro Volpato (mvolpato@mailbox.icom.it) wrote:

: AAARGHH

: How I can put a gliph with the white color inside on a SpeedButton?!!! (I use

: Borland's image edit)

: The white color seem to be alwais transparent!!!

: Tnx, Mauro

The transparent color is the color of the bottom left pixel of the bitmap.

Change it (and the transparent background you want) to another not used color.

Matthias


Win95 Taskbar Icon for each form

#517.TIP	From KWolak@mail.cbf.com Wed Dec 13 10:36:17 1995

Julian Bond <julian@shockwav.demon.co.uk> wrote:

|}I have a simple app with a main form and a second admin form. The second

|}form is shown with showmodal. Under win95, the second form produces a

|}second button in the taskbar. Is there any way of preventing this?

Get rid of the System Menu for the second form.

-------------------------------------------------------------

Kerry Sanders                 | "Cause when ya stop dreaming

ksanders@bham.mindspring.com  |    its time to die" - CHANGE

-------------------------------------------------------------


Repaint Icon while App is Minimized?

#518.TIP	From KWolak@mail.cbf.com Wed Dec 13 10:40:44 1995

>>I need to change my program's icon while it is minimized, to reflect a

>>change in state of the program.  I've figured out how to put the alternate

>>icon in a .RES file, and switch the application's icon at runtime, but the

>>icon on the screen soes not change until I force it to repaint (by Restoring

>>and then minimizing again).  Ed Salgado found a way to paint on the icon,

>>and I may have to resort to that.  Anyone know of a better way to force

>>a repaint?  CB.

>

>>--

>>============================================================================

>>   Clark Bremer - Sr. Software Engineer         mailto:clarkb@netstar.com

>>   NetStar Inc.                                  http://www.netstar.com

>>   10250 Valley View Rd - Minneapolis, MN - 55344      fax:(612) 943-8939

>

>I used a sample posted before to get an Icon from a resource. Just put

>a Timer on your form and put the icon changing code in the timer

>procedure. That worked for me in Win3.1x . Not in W95. Somehow the

>icon on the taskbar isn't updated unless you maximize/minimize ;-((

Just do an "InvalidateRect" followed by an "UpdateWindow" to force

a repaint of the icon.

David

--

David Brabant,             | E-mail: David.Brabant@csl.sni.be

Siemens Nixdorf (SNI),     | CIS:    100337,1733

Centre Software de Liège,  | X-400:  C=BE;A=RTT;P=SCN;O=SNI;OU1=LGG1;OU2=S1

2, rue des Fories,         |         S=BRABANT;G=DAVID

4020 Liège (BELGIUM)       | HTTP:   www.sni.de       www.csl.sni.be/~david


Printer positioning

#519.TIP	From KWolak@mail.cbf.com Wed Dec 13 10:51:55 1995

In article <458717126wnr@barron.demon.co.uk> Sol Barron <Sol@barron.demon.co.uk> writes:

>From: Sol Barron <Sol@barron.demon.co.uk>

>Subject: Printer positioning

>Date: Mon, 11 Dec 1995 22:38:49 +0100

>Can anyone point me in the right direction.

>I'm trying to print the results of some calculations. How do I position the various elements I

>want to print on the printer canvas. I know writeln will produce a CR at the end of the line, but

>how do I position lines accurately and how do I place text at specific point on a line?

>--

>Sol Barron          Internet: Sol@barron.demon.co.uk

>                  Compuserve: 100424,624

Hi Sol,

Try using the Printer.Canvas.TextOut(x,y,text). This will position at the x,y

coordinates on the Canvas

HTH

Cheers... Peter


Invalid Indirect Reference

#1000.IDE	From: jeroenp@dragons.nest.nl (Jeroen Pluimers)

Monday March 06 1995 15:16, ddavidso@metz.une.edu.au wrote:

 duea> When I try to compile the following with the IDE, I get an error

 duea> 136 "Invalid Indirect Reference"

This error is correct. The compiler needs explicit access to the scope where

the original type was declared.

Jeroen


SystemMenu Question

#1001.IDE	From: victorddm@delphi.com

<Grant Carpenter> writes:

>I couldn't find a way to alter a Form's system menu without going to API

>calls. While this is not my forte at all, I was able to modify and system

>menu for a maximized or normal form. Three questions:

Grant,

Look at the +BorderIcons property. That's what you are looking for.

Remember that when you see a plus (+) sign before the property name

that means you can double-click on the property name and it will expand

into more options.

Enjoy,


Delphi: edit source code in break mode?

#1002.IDE	From: jnhodges@nps.navy.mil (John N. Hodges)

In article etr@pipe2.pipeline.com, mwj@pipeline.com (Jin Mai) writes:

>

>In Delphi, is it possible to edit source code in break mode,

>resume to run mode and have the change in effect without

>recompile program?

>

>--

>Jin Mai        mwj@pipeline.com

No, but the code-compile-run cycle is so fast, you hardly notice the

difference.

Delphi produces compiled, machine code executables, so it can't do this like

the interpreted VB can.  This is a plus, in my book.

Delphi also has a real, integrated debugger.

---

*   LT Nick Hodges, USN                     Naval Postgraduate School

*

*   jnhodges@nps.navy.mil                Information Technology Management

*

*   CIS: 71563,2250 AOL: NHodges                   Monterey, CA

*

*   The opinions expressed above are entirely my own and not the Navy's.

*

*   Visit my homepage:  http://vislab-www.nps.navy.mil/~jnhodges

*


DELPHI merging menus in MDI app

#1003.IDE	From: james.obrien@yale.edu (James A. O'Brien)

In article <earache-2303951114020001@ip207.msp.primenet.com>

earache@primenet.com (Earache) writes:

>From: earache@primenet.com (Earache)

>Subject: DELPHI merging menus in MDI app

>Date: 23 Mar 1995 17:15:01 GMT

>I have a slight problem.  Any time my mdichildren merge their menus with

>the parent form, they always seem to nuke the parent's menu, even if I

>alter the groupIndex of both.  Doing according to the manual isn't helping

>much (surprise, surprise).

>Basically I just need to add a few menu items from the child's menu to the

>same menu in the parent, but it always nukes the parent.  It'd be way

>simpler if I could just keep the gosh darn menu in the child window, but

>some genius decided that wasn't the way things should be.

Merging works at the level fo the menu bar only.  If you just want to add a

few items, you must also duplicate the items you're "nuking" in the main menu.

 The idea is really to add whole items at the top level, rather than what

you're trying to do, although you _can_ fake it.

Jim.

From: Chuck Jazdzewski <cjaz@borland.com>

> I have a slight problem.  Any time my mdichildren merge their menus with

> the parent form, they always seem to nuke the parent's menu, even if I

> alter the groupIndex of both.  Doing according to the manual isn't helping

> much (surprise, surprise).

>

> Basically I just need to add a few menu items from the child's menu to the

> same menu in the parent, but it always nukes the parent.  It'd be way

> simpler if I could just keep the gosh darn menu in the child window, but

> some genius decided that wasn't the way things should be.

>

> Anyone know a solution or work around for my little problem here?

In menu merging top-level menu items of a child menu are always replace

top-level menu items in the parent with the same group index.  To avoid

the replacement ensure the items do not have the same group.

Consider the following menu definition for a fsMDIForm (if you copy this

text to the clipboard you can paste it into a form directly):

object MainMenu1: TMainMenu

  Left = 32

  Top = 40

  object File1: TMenuItem

    Caption = '&File'

    object New1: TMenuItem

      Caption = '&New'

    end

    object Open1: TMenuItem

      Caption = '&Open...'

    end

    object Save1: TMenuItem

      Caption = '&Save'

    end

    object SaveAs1: TMenuItem

      Caption = 'Save &As...'

    end

    object N1: TMenuItem

      Caption = '-'

    end

    object Exit1: TMenuItem

      Caption = 'E&xit'

    end

  end

  object Edit1: TMenuItem

    Caption = '&Edit'

    GroupIndex = 1

    object Cut1: TMenuItem

      Caption = 'Cu&t'

    end

    object Copy1: TMenuItem

      Caption = '&Copy'

    end

    object Paste1: TMenuItem

      Caption = '&Paste'

    end

  end

  object Window1: TMenuItem

    Caption = '&Window'

    GroupIndex = 3

    object Tile1: TMenuItem

      Caption = '&Tile'

    end

    object Cascade1: TMenuItem

      Caption = '&Cascade'

    end

    object ArrangeIcons1: TMenuItem

      Caption = '&Arrange Icons'

    end

  end

end

And the following for the a child form:

object MainMenu1: TMainMenu

  Left = 16

  Top = 24

  object Edit1: TMenuItem

    Caption = '&Edit'

    GroupIndex = 1

    object Cut1: TMenuItem

      Caption = 'Cu&t'

    end

    object Copy1: TMenuItem

      Caption = '&Copy'

    end

    object Paste1: TMenuItem

      Caption = '&Paste'

    end

  end

  object View1: TMenuItem

    Caption = '&View'

    GroupIndex = 2

    object Full1: TMenuItem

      Caption = '&Full'

    end

    object Partial1: TMenuItem

      Caption = '&Partial'

    end

  end

end

When these two menus are merged the "File" menu will still be in the parent.

The "Edit" menu of the parent will be replaced by the child (since they both

have a group index of 1), the "View" menu will be inserted (since the parent

menu doesn't have an item with group index of 2) and the "Window" menu will

be left at the end.  I hope this explaination helps.

BTW, the genius that disallowed MDI children from having menus was the

original

implementor(s) of Microsoft Windows.  Due to some structural desisions child

windows of any kind cannot have menus of their own.  The best we can do is

merging, as VCL implements, or right mouse click for local or context menus

which VCL also implements.

Chuck Jazdzewski (cjaz@borland.com)


Project .DSM file?

#1004.IDE	From: muftiteg@netcom.com

In <3l242f$8n7@its.hooked.net>, jinx@hooked.net (Jeff Wakeman) writes:

>What is stored in the .DSM file? I've got a small two-form app that results

in

>a 500K (unoptimized with debug info) .EXE file. I recently noticed that

Jeff,

  This is the precompiled "header" file.  Analagous to the .CSM files for

BC++ v4.x.  I'm not sure exactly what is stored in there within a Pascal

environment, but I have guessed that it handles the interface sections of

the unit files.

  -- Mufti

From: Rick Rutt <rrutt@delphi.com>

<muftiteg@netcom.com> writes:

>  This is the precompiled "header" file.  Analagous to the .CSM files for

>BC++ v4.x.  I'm not sure exactly what is stored in there within a Pascal

>environment, but I have guessed that it handles the interface sections of

>the unit files.

In Borland Pascal v7.0, the compiled .TPU files stored their own

interface information.  The "Uses" reference in other sourch files reads

the .TPU file to get the "precompiled" header information.

I am assuming that Delphi's .DCU files work the same as .TPU files.

This is the whole reason they are not just simple .OBJ files.

-- Rick

--

(Rick Rutt is a system architect living and working in Midland, Michigan.)

From: Chuck Jazdzewski <cjaz@borland.com>

> What is stored in the .DSM file? I've got a small two-form app that results

in

> a 500K (unoptimized with debug info) .EXE file. I recently noticed that

> there's also a huge (over 650K) .DSM file there. Some kind of symbol info is

> in it, because if I take it away Delphi complains about missing symbol info

> when I open the project (yet the project will still open, compile, & run --

> but not save).

>

> When I save the project and all the PAS files (via "Save as") to another

> directory, the .DSM doesn't go with it, which concerns me since it's

> apparently a necessary file.

>

> On a perhaps unrelated matter, this same project won't link properly when I

> select EXE optimization: I get an error message saying that "TIMETRAK.EXE is

> not an .EXE file" (if it's on a local drive) or "Cannot write TIMETRAK.EXE /

> disk full?" (if it's on a NetWare drive).

>

> Anybody got any ideas? Delphi seems a much better development platform than

> either BP7 or Paradox, but this odd behaviour concerns me.

The browser uses the compiler symbol table from the last successful compile of

the application to provide symbolic browsing and reference information. The

DSM file saves this information so you can access it again after you have

closed

Delphi and restarted. This saves you from having to successfully compile in

the

current session of Delphi to use the browser.

If you don't want the DSM file around turn the "Desktop contents" option to

"Desktop only" in the Options|Environment|Preferences option page.

BTW, because the desktop (DSK) file stores a reference to the DSM file

deleting

it will cause the loading of that desktop to complain and the browser will be

inactive until the next successful compile.

Chuck Jazdzewski (cjaz@borland.com)

Delphi Development

From: joser@dorsai.dorsai.org (joser)

In article <3l6sg4$lfg@druid.borland.com>, Chuck Jazdzewski <cjaz@borland.com>

says:

>

>> On a perhaps unrelated matter, this same project won't link properly when I

>> select EXE optimization: I get an error message saying that "TIMETRAK.EXE

is

>> not an .EXE file" (if it's on a local drive) or "Cannot write TIMETRAK.EXE

/

>> disk full?" (if it's on a NetWare drive).

>>

>> Anybody got any ideas? Delphi seems a much better development platform than

>> either BP7 or Paradox, but this odd behaviour concerns me.

>

>The browser uses the compiler symbol table from the last successful compile

of

>the application to provide symbolic browsing and reference information. The

>DSM file saves this information so you can access it again after you have

closed

>Delphi and restarted. This saves you from having to successfully compile in

the

>current session of Delphi to use the browser.

>

>If you don't want the DSM file around turn the "Desktop contents" option to

>"Desktop only" in the Options|Environment|Preferences option page.

>

>BTW, because the desktop (DSK) file stores a reference to the DSM file

deleting

>it will cause the loading of that desktop to complain and the browser will be

>inactive until the next successful compile.

>

>Chuck Jazdzewski (cjaz@borland.com)

>Delphi Development

Yeah but nobody answered the second question about

the error the system gives when you turn the optimization on. I have the

exact same problem and I am running on a stand alone system (no network).

What Is going on wit Delphi?

Thanks.

>


Delphi Easter Egg.

#1005.IDE	From: Marc@landscap.demon.co.uk (Marc Palmer)

In article: <3lc2uf$6ru@druid.borland.com>  Chuck Jazdzewski

<cjaz@borland.com> writes:

>

> > In <3l7v1q$jmo@panix3.panix.com> sal@panix.com (Salvatore Denaro)

> > writes:

> >

> >

> > >I think I've found the first egg of the season.

> >

> > >Go to Database Desktop.

> > >Help->About

> >

> > >Type "delphi" without quotes :)

> >

> > >I am using the desktop release.

Me too - but when I press 'i' (as mentioned by another poster) I just get

a little bit of text at the bottom left of the dialog saying something like

'Internal: 6,049J Lego 3.045' Which isn't much fun at all!

********************************************************************

* Marc P.                               E-Mail me for PGP 2.6 key  *

********************************************************************

From: ()

In message <3ldllh$n84@clarknet.clark.net>, tax@clark.net (Tax Analysts)

writes:

>Bob Swart (bobs@dragons.nest.nl) wrote:

>

>:  > Go to Database Desktop.

>:  > Help->About

>:  > Type "delphi" without quotes :)

>: Try ALT+AND

>

>I like ALT-and better, since typing 'delphi' didn't do a damn thing

>when I did it.

>

>Kendall

Try ALT+TEAM

(a very long list of people)

Kevin F.

From: hallvard@falcon.no (Hallvard Vassbotn)

In <Pine.ULT.3.91.950330192742.3231A-100000@zeus.towson.edu> "Travis L. Reno"

<reno@zeus.towson.edu> writes:

>On 29 Mar 1995, John Leon wrote:

>> From the Delphi Help->About box, hold down ALT and type any of the

>> following:

>>

>> 1. team

>> 2. developers

>> 3. and   (for Anders)

>>

>> Have fun!

>Now that's what I call an Easter Egg!

Another one is Alt+VERSION (don't hold your breath, though).

--

 Hallvard Vassbotn  | Falcon AS (a Reuters company) | Without programmers,

 hallvard@falcon.no | Stranden 1, 0250 OSLO, Norway | the world would stop!

From: uk.twyford.rnelson@wpo.borland.com (Roy Nelson)

In article <3lej62$rq4@gatekeeper.bgs.com> () writes:

>From: ()

>Subject: Re: Delphi Easter Egg.

>Date: 30 Mar 1995 15:36:34 GMT

>In message <3ldllh$n84@clarknet.clark.net>, tax@clark.net (Tax Analysts)

>writes:

>>Bob Swart (bobs@dragons.nest.nl) wrote:

>>

>>:  > Go to Database Desktop.

>>:  > Help->About

>>:  > Type "delphi" without quotes :)

>>: Try ALT+AND

>>

>>I like ALT-and better, since typing 'delphi' didn't do a damn thing

>>when I did it.

>>

>>Kendall

>Try ALT+TEAM

>(a very long list of people)

>Kevin F.

One thing you should remember is to use a 256 color driver to see Anders. A

Lesser driver will not work.

--------------------------------------

-- Roy Nelson

-- Borland European Escalation Center

--------------------------------------


Debuging DLL not supported

#1006.IDE	From: Steve Teixeira <steixeir@borland.com>

yassine@america.com (Maher Yassine) wrote:

>

> I have tried to use the DELPHI debuger to step trough a DELPHI DLL

> source.  It does not seems to stop at the break point inside the DLL.

> Did anybody encouter that?

>

The integrated debugger doesn't support debugging DLLs.  You need to use

Turbo Debugger for Windows 4.6 for this.

        -Steve Teixeira

         steixeir@borland.com


EGPFault on .DPR

#1007.IDE	From: koterski@genghis (Steve Koterski)

Steve Wiser (steve.wiser@richcon.com) wrote:

: I am getting a EGPFault on my .DPR file whenever I attempt to

: run it.  The message is a fault at location 0001:2972.  Since

: Delphi says were not supposed to have to modify this file

: because it is completely Delphi generated what's going on?

: I can do a step over and it clears the error.  The

: application runs giving me a new message window with the same

: error identified.  If I click OK here it clears the error

: taking me directly into the application where everything

: works find just the way I wanted it to function.

It is true that the DPR file for your application is written by Delphi

and that you will seldom, if ever, need to modify this file. But it is

also true that this file is just another program file -- one that you

can open in the program editor and view the contents.

The DPR file contains the calls to Application.Create, one for each of

the Forms in your application. It is entirely conceivable that some-

thing in one of your Forms is causing a GPF-level error and that it

shows up when the Create method for that Form is called, rather than

in the unit containing the Form. To help you narrow down where the

problem is, open the DPR file in the program editor and set a break

point just prior to any calling of the Application.Create method. Then

run the application and step through that portion of the DPR file to

see which of your Forms the error is associated with.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


TROUBLE RUNNING DELPHI PROGRAMS FROM DELPHI

#2019.IDE	From BORLAND

Delphi's integrated debugger is a feature of the IDE that allows

you to execute, step, trace, and otherwise debug your Delphi

applications.  By default, Delphi's integrated debugger is enabled (via

Options|Project|Integrated Debugging) on startup of Delphi.

The debugger handles certain interrupts and operating system debugger

hooks in an effort to trap General Protection Faults and other types

of exceptions.  Other programs that attempt to handle exceptions in the

same way will quite possibly conflict with the integrated debugger.

DataSafe is one example of a program that conficts with the integrated

debugger.  Classic symptoms include, Delphi not recognizing that you've

stopped your program and getting kicked into DOS without warning at

various stages.

To test for a debugger conflict, compiling the program from Delphi,

and run it from File Manager.  If it runs,, then disable the integrated

debugger, and run your application.  If it still runs, then the problem

is most likely a conflict between the exception-handling software and

the integrated debugger.

There are two ways to fix this.   The first is to remove the

conflicting software.   The other is to disable the integrated

debugger by un-selecting Options|Enviroment|Integrated Debugging.


BDE error codes and descriptions

#00000001.BDE	From Lloyds help File

  The code listed at the end of this topic creates ERRLIST.TXT containing a list of error codes, along with the

descriptions returned by DbiGetErrorString.  This is essentially a dump; it tries to get every possible error code.

Most return null strings and are filtered out. Some return valid strings that aren't real error messages.

     0  0000  Successful completion.

    33  0021  System Error

    34  0022  Object of Interest Not Found

    35  0023  Physical Data Corruption

    36  0024  I/O Related Error

    37  0025  Resource or Limit Error

    38  0026  Data Integrity Violation

    39  0027  Invalid Request

    40  0028  Lock Violation

    41  0029  Access/Security Violation

    42  002A  Invalid Context

    43  002B  OS Error

    44  002C  Network Error

    45  002D  Optional Parameter

    46  002E  Query Processor

    47  002F  Version Mismatch

    48  0030  Capability Not Supported

    49  0031  System Configuration Error

    50  0032  Warning

    51  0033  Miscellaneous

    52  0034  Compatibility Error

    62  003E  Driver Specific Error

    63  003F  Internal Symbol

   256  0100  KEYVIOL

   257  0101  PROBLEMS

   258  0102  CHANGED

   512  0200  Production Index file missing, corrupt or cannot interpret index key

   513  0201  Open Read Only

   514  0202  Open the table in read only mode

   515  0203  Open and Detach

   516  0204  Open the table and detach the Production Index file

   517  0205  Fail Open

   518  0206  Do not open the table

   519  0207  Convert Non-dBase Index

   520  0208  Convert production index to dBase format

   521  0209  BLOB file not found

   522  020A  Open without blob file

   523  020B  Open the table without the blob file

   524  020C  Empty all blob fields

   525  020D  Reinitialize BLOB file and LOSE all blobs

   526  020E  Fail Open

   527  020F  Do not open the table

   528  0210  Import Non-dBASE BLOB file

   529  0211  Import BLOB file to dBASE format

   530  0212  Open as Non-dBASE table

   531  0213  Open Table and BLOB file in its native format

   532  0214  Production Index Language driver mismatch

   533  0215  Production Index damaged

   534  0216  Rebuild Production Index

   535  0217  Rebuild all the Production Indexes

  1024  0400  Lookup table not found or corrupt

  1025  0401  Blob file not found or corrupt

  1026  0402  Open Read Only

  1027  0403  Open the table in read only mode

  1028  0404  Fail Open

  1029  0405  Do not open the table

  1030  0406  Remove lookup

  1031  0407  Remove link to lookup table

  2048  0800  Reading records

  2049  0801  Sorting records

  2050  0802  Writing records

  2051  0803  Merging

  2052  0804  Steps Completed

  2053  0805  Packing records

  2309  0905  LIKE

  2310  0906  NOT

  2320  0910  INSERT

  2321  0911  DELETE

  2322  0912  CHANGETO

  2323  0913  CHANGE

  2324  0914  TO

  2325  0915  FIND

  2326  0916  CALC

  2327  0917  COUNT

  2328  0918  SUM

  2329  0919  AVERAGE

  2330  091A  MAX

  2331  091B  MIN

  2332  091C  ALL

  2333  091D  UNIQUE

  2334  091E  BLANK

  2335  091F  TODAY

  2336  0920  AS

  2337  0921  DESCENDING

  2338  0922  OR

  2339  0923  ONLY

  2340  0924  EVERY

  2341  0925  NO

  2342  0926  EXACTLY

  2343  0927  SET

  2347  092B  %time

  2348  092C  %date

  2353  0931  %lower

  2354  0932  %upper

  2355  0933  %trim

  2356  0934  %substring

  2364  093C  __QB0000

  2365  093D  ANSWER

  2366  093E  DELETED

  2367  093F  INSERTED

  2368  0940  CHANGED

  2369  0941  ERRORDEL

  2370  0942  ERRORINS

  2371  0943  ERRORCHG

  2372  0944  __XLTTMP

  2373  0945  __QBEDIC

  2405  0965  JAN

  2406  0966  FEB

  2407  0967  MAR

  2408  0968  APR

  2409  0969  MAY

  2410  096A  JUN

  2411  096B  JUL

  2412  096C  AUG

  2413  096D  SEP

  2414  096E  OCT

  2415  096F  NOV

  2416  0970  DEC

  2423  0977  INSERTED.DB

  2424  0978  CHANGED.DB

  2425  0979  DELETED.DB

  2426  097A  ANSWER.DB

  2427  097B  blank

  2428  097C  Sum of

  2429  097D  Average of

  2430  097E  Count of

  2431  097F  Max of

  2432  0980  Min of

  2433  0981  GROUPBY

  2434  0982  FIELDORDER

  2435  0983  SORT

  2436  0984  ANSWER

  2437  0985  TYPE

  2438  0986  OPTIONS

  2440  0988  GENERATE AUXILIARY TABLES

  2441  0989  NO AUXILIARY TABLES

  2442  098A  SERVER

  2443  098B  LOCAL

  2444  098C  CANNED

  2445  098D  LIVE

  2446  098E  SPEED

  2447  098F  %extract

  2448  0990  DATE

  2449  0991  TIME

  2450  0992  YEAR

  2451  0993  MONTH

  2452  0994  DAY

  2453  0995  HOUR

  2454  0996  MINUTE

  2455  0997  SECOND

  8449  2101  Cannot open a system file.

  8450  2102  I/O error on a system file.

  8451  2103  Data structure corruption.

  8452  2104  Cannot find Engine configuration file.

  8453  2105  Cannot write to Engine configuration file.

  8454  2106  Cannot initialize with different configuration file.

  8455  2107  System has been illegally re-entered.

  8456  2108  Cannot locate IDAPI01.DLL

  8457  2109  Cannot load IDAPI01.DLL

  8458  210A  Cannot load an IDAPI service library

  8705  2201  At beginning of table.

  8706  2202  At end of table.

  8707  2203  Record moved because key value changed.

  8708  2204  Record/Key deleted.

  8709  2205  No current record.

  8710  2206  Could not find record.

  8711  2207  End of BLOB.

  8712  2208  Could not find object.

  8713  2209  Could not find family member.

  8714  220A  BLOB file is missing.

  8715  220B  Could not find language driver.

  8961  2301  Corrupt table/index header.

  8962  2302  Corrupt file - other than header.

  8963  2303  Corrupt Memo/BLOB file.

  8965  2305  Corrupt index.

  8966  2306  Corrupt lock file.

  8967  2307  Corrupt family file.

  8968  2308  Corrupt or missing .VAL file.

  8969  2309  Foreign index file format.

  9217  2401  Read failure.

  9218  2402  Write failure.

  9219  2403  Cannot access directory.

  9220  2404  File Delete operation failed.

  9221  2405  Cannot access file.

  9222  2406  Access to table disabled because of previous error.

  9473  2501  Insufficient memory for this operation.

  9474  2502  Not enough file handles.

  9475  2503  Insufficient disk space.

  9476  2504  Temporary table resource limit.

  9477  2505  Record size is too big for table.

  9478  2506  Too many open cursors.

  9479  2507  Table is full.

  9480  2508  Too many sessions from this workstation.

  9481  2509  Serial number limit (Paradox).

  9482  250A  Some internal limit (see context).

  9483  250B  Too many open tables.

  9484  250C  Too many cursors per table.

  9485  250D  Too many record locks on table.

  9486  250E  Too many clients.

  9487  250F  Too many indexes on table.

  9488  2510  Too many sessions.

  9489  2511  Too many open databases.

  9490  2512  Too many passwords.

  9491  2513  Too many active drivers.

  9492  2514  Too many fields in Table Create.

  9493  2515  Too many table locks.

  9494  2516  Too many open BLOBs.

  9495  2517  Lock file has grown too large.

  9496  2518  Too many open queries.

  9498  251A  Too many BLOBs.

  9729  2601  Key violation.

  9730  2602  Minimum validity check failed.

  9731  2603  Maximum validity check failed.

  9732  2604  Field value required.

  9733  2605  Master record missing.

  9734  2606  Master has detail records. Cannot delete or modify.

  9735  2607  Master table level is incorrect.

  9736  2608  Field value out of lookup table range.

  9737  2609  Lookup Table Open operation failed.

  9738  260A  Detail Table Open operation failed.

  9739  260B  Master Table Open operation failed.

  9740  260C  Field is blank.

  9741  260D  Link to master table already defined.

  9742  260E  Master table is open.

  9743  260F  Detail table(s) exist.

  9744  2610  Master has detail records. Cannot empty it.

  9745  2611  Self referencing referential integrity must be entered one at a time with no other

changes to the table

  9746  2612  Detail table is open.

  9747  2613  Cannot make this master a detail of another table if its details are not empty.

  9748  2614  Referential integrity fields must be indexed.

  9749  2615  A table linked by referential integrity requires password to open.

  9750  2616  Field(s) linked to more than one master.

  9985  2701  Number is out of range.

  9986  2702  Invalid parameter.

  9987  2703  Invalid file name.

  9988  2704  File does not exist.

  9989  2705  Invalid option.

  9990  2706  Invalid handle to the function.

  9991  2707  Unknown table type.

  9992  2708  Cannot open file.

  9993  2709  Cannot redefine primary key.

  9994  270A  Cannot change this RINTDesc.

  9995  270B  Foreign and primary key do not match.

  9996  270C  Invalid modify request.

  9997  270D  Index does not exist.

  9998  270E  Invalid offset into the BLOB.

  9999  270F  Invalid descriptor number.

 10000  2710  Invalid field type.

 10001  2711  Invalid field descriptor.

 10002  2712  Invalid field transformation.

 10003  2713  Invalid record structure.

 10004  2714  Invalid descriptor.

 10005  2715  Invalid array of index descriptors.

 10006  2716  Invalid array of validity check descriptors.

 10007  2717  Invalid array of referential integrity descriptors.

 10008  2718  Invalid ordering of tables during restructure.

 10009  2719  Name not unique in this context.

 10010  271A  Index name required.

 10011  271B  Invalid session handle.

 10012  271C  invalid restructure operation.

 10013  271D  Driver not known to system.

 10014  271E  Unknown database.

 10015  271F  Invalid password given.

 10016  2720  No callback function.

 10017  2721  Invalid callback buffer length.

 10018  2722  Invalid directory.

 10019  2723  Translate Error. Value out of bounds.

 10020  2724  Cannot set cursor of one table to another.

 10021  2725  Bookmarks do not match table.

 10022  2726  Invalid index/tag name.

 10023  2727  Invalid index descriptor.

 10024  2728  Table does not exist.

 10025  2729  Table has too many users.

 10026  272A  Cannot evaluate Key or Key does not pass filter condition.

 10027  272B  Index already exists.

 10028  272C  Index is open.

 10029  272D  Invalid BLOB length.

 10030  272E  Invalid BLOB handle in record buffer.

 10031  272F  Table is open.

 10032  2730  Need to do (hard) restructure.

 10033  2731  Invalid mode.

 10034  2732  Cannot close index.

 10035  2733  Index is being used to order table.

 10036  2734  Unknown user name or password.

 10037  2735  Multi-level cascade is not supported.

 10038  2736  Invalid field name.

 10039  2737  Invalid table name.

 10040  2738  Invalid linked cursor expression.

 10041  2739  Name is reserved.

 10042  273A  Invalid file extension.

 10043  273B  Invalid language Driver.

 10044  273C  Alias is not currently opened.

 10045  273D  Incompatible record structures.

 10046  273E  Name is reserved by DOS.

 10047  273F  Destination must be indexed.

 10048  2740  Invalid index type

 10049  2741  Language Drivers of Table and Index do not match

 10050  2742  Filter handle is invalid

 10051  2743  Invalid Filter

 10052  2744  Invalid table create request

 10053  2745  Invalid table delete request

 10054  2746  Invalid index create request

 10055  2747  Invalid index delete request

 10056  2748  Invalid table specified

 10058  274A  Invalid Time.

 10059  274B  Invalid Date.

 10060  274C  Invalid Datetime

 10061  274D  Tables in different directories

 10062  274E  Mismatch in the number of arguments

 10063  274F  Function not found in service library.

 10064  2750  Must use baseorder for this operation.

 10065  2751  Invalid procedure name

 10241  2801  Record locked by another user.

 10242  2802  Unlock failed.

 10243  2803  Table is busy.

 10244  2804  Directory is busy.

 10245  2805  File is locked.

 10246  2806  Directory is locked.

 10247  2807  Record already locked by this session.

 10248  2808  Object not locked.

 10249  2809  Lock time out.

 10250  280A  Key group is locked.

 10251  280B  Table lock was lost.

 10252  280C  Exclusive access was lost.

 10253  280D  Table cannot be opened for exclusive use.

 10254  280E  Conflicting record lock in this session.

 10255  280F  A deadlock was detected.

 10256  2810  A user transaction is already in progress.

 10257  2811  No user transaction is currently in progress.

 10258  2812  Record lock failed.

 10259  2813  Couldn't perform the edit because another user changed the record.

 10260  2814  Couldn't perform the edit because another user deleted or moved the record.

 10497  2901  Insufficient field rights for operation.

 10498  2902  Insufficient table rights for operation. Password required.

 10499  2903  Insufficient family rights for operation.

 10500  2904  This directory is read only.

 10501  2905  Database is read only.

 10502  2906  Trying to modify read-only field.

 10503  2907  Encrypted dBASE tables not supported.

 10504  2908  Insufficient SQL rights for operation.

 10753  2A01  Field is not a BLOB.

 10754  2A02  BLOB already opened.

 10755  2A03  BLOB not opened.

 10756  2A04  Operation not applicable.

 10757  2A05  Table is not indexed.

 10758  2A06  Engine not initialized.

 10759  2A07  Attempt to re-initialize Engine.

 10760  2A08  Attempt to mix objects from different sessions.

 10761  2A09  Paradox driver not active.

 10762  2A0A  Driver not loaded.

 10763  2A0B  Table is read only.

 10764  2A0C  No associated index.

 10765  2A0D  Table(s) open. Cannot perform this operation.

 10766  2A0E  Table does not support this operation.

 10767  2A0F  Index is read only.

 10768  2A10  Table does not support this operation because it is not uniquely indexed.

 10769  2A11  Operation must be performed on the current session.

 10770  2A12  Invalid use of keyword.

 10771  2A13  Connection is in use by another statement.

 10772  2A14  Passthrough SQL connection must be shared

 11009  2B01  Invalid function number.

 11010  2B02  File or directory does not exist.

 11011  2B03  Path not found.

 11012  2B04  Too many open files. You may need to increase MAXFILEHANDLE limit in IDAPI

configuration.

 11013  2B05  Permission denied.

 11014  2B06  Bad file number.

 11015  2B07  Memory blocks destroyed.

 11016  2B08  Not enough memory.

 11017  2B09  Invalid memory block address.

 11018  2B0A  Invalid environment.

 11019  2B0B  Invalid format.

 11020  2B0C  Invalid access code.

 11021  2B0D  Invalid data.

 11023  2B0F  Device does not exist.

 11024  2B10  Attempt to remove current directory.

 11025  2B11  Not same device.

 11026  2B12  No more files.

 11027  2B13  Invalid argument.

 11028  2B14  Argument list is too long.

 11029  2B15  Execution format error.

 11030  2B16  Cross-device link.

 11041  2B21  Math argument.

 11042  2B22  Result is too large.

 11043  2B23  File already exists.

 11047  2B27  Unknown internal operating system error.

 11058  2B32  Share violation.

 11059  2B33  Lock violation.

 11060  2B34  Critical DOS Error.

 11061  2B35  Drive not ready.

 11108  2B64  Not exact read/write.

 11109  2B65  Operating system network error.

 11110  2B66  Error from NOVELL file server.

 11111  2B67  NOVELL server out of memory.

 11112  2B68  Record already locked by this workstation.

 11113  2B69  Record not locked.

 11265  2C01  Network initialization failed.

 11266  2C02  Network user limit exceeded.

 11267  2C03  Wrong .NET file version.

 11268  2C04  Cannot lock network file.

 11269  2C05  Directory is not private.

 11270  2C06  Multiple .NET files in use.

 11271  2C07  Unknown network error.

 11272  2C08  Not initialized for accessing network files.

 11273  2C09  SHARE not loaded. It is required to share local files.

 11274  2C0A  Not on a network. Not logged in or wrong network driver.

 11275  2C0B  Lost communication with SQL server.

 11521  2D01  Optional parameter is required.

 11522  2D02  Invalid optional parameter.

 11777  2E01  obsolete

 11778  2E02  obsolete

 11779  2E03  Ambiguous use of ! (inclusion operator).

 11780  2E04  obsolete

 11781  2E05  obsolete

 11782  2E06  A SET operation cannot be included in its own grouping.

 11783  2E07  Only numeric and date/time fields can be averaged.

 11784  2E08  Invalid expression.

 11785  2E09  Invalid OR expression.

 11786  2E0A  obsolete

 11787  2E0B  bitmap

 11788  2E0C  CALC expression cannot be used in INSERT, DELETE, CHANGETO and SET rows.

 11789  2E0D  Type error in CALC expression.

 11790  2E0E  CHANGETO can be used in only one query form at a time.

 11791  2E0F  Cannot modify CHANGED table.

 11792  2E10  A field can contain only one CHANGETO expression.

 11793  2E11  A field cannot contain more than one expression to be inserted.

 11794  2E12  obsolete

 11795  2E13  CHANGETO must be followed by the new value for the field.

 11796  2E14  Checkmark or CALC expressions cannot be used in FIND queries.

 11797  2E15  Cannot perform operation on CHANGED table together with a CHANGETO query.

 11798  2E16  chunk

 11799  2E17  More than 255 fields in ANSWER table.

 11800  2E18  AS must be followed by the name for the field in the ANSWER table.

 11801  2E19  DELETE can be used in only one query form at a time.

 11802  2E1A  Cannot perform operation on DELETED table together with a DELETE query.

 11803  2E1B  Cannot delete from the DELETED table.

 11804  2E1C  Example element is used in two fields with incompatible types or with a BLOB.

 11805  2E1D  Cannot use example elements in an OR expression.

 11806  2E1E  Expression in this field has the wrong type.

 11807  2E1F  Extra comma found.

 11808  2E20  Extra OR found.

 11809  2E21  One or more query rows do not contribute to the ANSWER.

 11810  2E22  FIND can be used in only one query form at a time.

 11811  2E23  FIND cannot be used with the ANSWER table.

 11812  2E24  A row with GROUPBY must contain SET operations.

 11813  2E25  GROUPBY can be used only in SET rows.

 11814  2E26  Use only INSERT, DELETE, SET or FIND in leftmost column.

 11815  2E27  Use only one INSERT, DELETE, SET or FIND per line.

 11816  2E28  Syntax error in expression.

 11817  2E29  INSERT can be used in only one query form at a time.

 11818  2E2A  Cannot perform operation on INSERTED table together with an INSERT query.

 11819  2E2B  INSERT, DELETE, CHANGETO and SET rows may not be checked.

 11820  2E2C  Field must contain an expression to insert (or be blank).

 11821  2E2D  Cannot insert into the INSERTED table.

 11822  2E2E  Variable is an array and cannot be accessed.

 11823  2E2F  Label

 11824  2E30  Rows of example elements in CALC expression must be linked.

 11825  2E31  Variable name is too long.

 11826  2E32  Query may take a long time to process.

 11827  2E33  Reserved word or one that can't be used as a variable name.

 11828  2E34  Missing comma.

 11829  2E35  Missing ).

 11830  2E36  Missing right quote.

 11831  2E37  Cannot specify duplicate column names.

 11832  2E38  Query has no checked fields.

 11833  2E39  Example element has no defining occurrence.

 11834  2E3A  No grouping is defined for SET operation.

 11835  2E3B  Query makes no sense.

 11836  2E3C  Cannot use patterns in this context.

 11837  2E3D  Date does not exist.

 11838  2E3E  Variable has not been assigned a value.

 11839  2E3F  Invalid use of example element in summary expression.

 11840  2E40  Incomplete query statement. Query only contains a SET definition.

 11841  2E41  Example element with ! makes no sense in expression.

 11842  2E42  Example element cannot be used more than twice with a ! query.

 11843  2E43  Row cannot contain expression.

 11844  2E44  obsolete

 11845  2E45  obsolete

 11846  2E46  No permission to insert or delete records.

 11847  2E47  No permission to modify field.

 11848  2E48  Field not found in table.

 11849  2E49  Expecting a column separator in table header.

 11850  2E4A  Expecting a column separator in table.

 11851  2E4B  Expecting column name in table.

 11852  2E4C  Expecting table name.

 11853  2E4D  Expecting consistent number of columns in all rows of table.

 11854  2E4E  Cannot open table.

 11855  2E4F  Field appears more than once in table.

 11856  2E50  This DELETE, CHANGE or INSERT query has no ANSWER.

 11857  2E51  Query is not prepared. Properties unknown.

 11858  2E52  DELETE rows cannot contain quantifier expression.

 11859  2E53  Invalid expression in INSERT row.

 11860  2E54  Invalid expression in INSERT row.

 11861  2E55  Invalid expression in SET definition.

 11862  2E56  row use

 11863  2E57  SET keyword expected.

 11864  2E58  Ambiguous use of example element.

 11865  2E59  obsolete

 11866  2E5A  obsolete

 11867  2E5B  Only numeric fields can be summed.

 11868  2E5C  Table is write protected.

 11869  2E5D  Token not found.

 11870  2E5E  Cannot use example element with ! more than once in a single row.

 11871  2E5F  Type mismatch in expression.

 11872  2E60  Query appears to ask two unrelated questions.

 11873  2E61  Unused SET row.

 11874  2E62  INSERT, DELETE, FIND, and SET can be used only in the leftmost column.

 11875  2E63  CHANGETO cannot be used with INSERT, DELETE, SET or FIND.

 11876  2E64  Expression must be followed by an example element defined in a SET.

 11877  2E65  Lock failure.

 11878  2E66  Expression is too long.

 11879  2E67  Refresh exception during query.

 11880  2E68  Query canceled.

 11881  2E69  Unexpected Database Engine error.

 11882  2E6A  Not enough memory to finish operation.

 11883  2E6B  Unexpected exception.

 11884  2E6C  Feature not implemented yet in query.

 11885  2E6D  Query format is not supported.

 11886  2E6E  Query string is empty.

 11887  2E6F  Attempted to prepare an empty query.

 11888  2E70  Buffer too small to contain query string.

 11889  2E71  Query was not previously parsed or prepared.

 11890  2E72  Function called with bad query handle.

 11891  2E73  QBE syntax error.

 11892  2E74  Query extended syntax field count error.

 11893  2E75  Field name in sort or field clause not found.

 11894  2E76  Table name in sort or field clause not found.

 11895  2E77  Operation is not supported on BLOB fields.

 11896  2E78  General BLOB error.

 11897  2E79  Query must be restarted.

 11898  2E7A  Unknown answer table type.

 11926  2E96  Blob cannot be used as grouping field.

 11927  2E97  Query properties have not been fetched.

 11928  2E98  Answer table is of unsuitable type.

 11929  2E99  Answer table is not yet supported under server alias.

 11930  2E9A  Non-null blob field required. Can't insert records

 11931  2E9B  Unique index required to perform changeto

 11932  2E9C  Unique index required to delete records

 11933  2E9D  Update of table on the server failed.

 11934  2E9E  Can't process this query remotely.

 11935  2E9F  Unexpected end of command.

 11936  2EA0  Parameter not set in query string.

 11937  2EA1  Query string is too long.

 12033  2F01  Interface mismatch. Engine version different.

 12034  2F02  Index is out of date.

 12035  2F03  Older version (see context).

 12036  2F04  .VAL file is out of date.

 12037  2F05  BLOB file version is too old.

 12038  2F06  Query and Engine DLLs are mismatched.

 12289  3001  Capability not supported.

 12290  3002  Not implemented yet.

 12291  3003  SQL replicas not supported.

 12292  3004  Non-blob column in table required to perform operation.

 12293  3005  Multiple connections not supported.

 12545  3101  Invalid database alias specification.

 12546  3102  Unknown database type.

 12547  3103  Corrupt system configuration file.

 12548  3104  Network type unknown.

 12549  3105  Not on the network.

 12550  3106  Invalid configuration parameter.

 12801  3201  Object implicitly dropped.

 12802  3202  Object may be truncated.

 12803  3203  Object implicitly modified.

 12804  3204  Should field constraints be checked?

 12805  3205  Validity check field modified.

 12806  3206  Table level changed.

 12807  3207  Copy linked tables?

 12809  3209  Object implicitly truncated.

 12810  320A  Validity check will not be enforced.

 12811  320B  Multiple records found, but only one was expected.

 12812  320C  Field will be trimmed, cannot put master records into PROBLEM table.

 13057  3301  File already exists.

 13058  3302  BLOB has been modified.

 13059  3303  General SQL error.

 13060  3304  Table already exists.

 13061  3305  Paradox 1.0 tables are not supported.

 13313  3401  Different sort order.

 13314  3402  Directory in use by earlier version of Paradox.

 13315  3403  Needs Paradox 3.5-compatible language driver.

 14849  3A01  SYSTEM

 14850  3A02  DRIVERS

 14851  3A03  DATABASES

 14853  3A05  VERSION

 14854  3A06  NET TYPE

 14855  3A07  NET DIR

 14856  3A08  LOCAL SHARE

 14857  3A09  LANGDRIVER

 14858  3A0A  LANGDRVDIR

 14859  3A0B  MINBUFSIZE

 14860  3A0C  MAXBUFSIZE

 14861  3A0D  LOCKRETRY

 14862  3A0E  SYSFLAGS

 14864  3A10  SQLQRYMODE

 14865  3A11  LOW MEMORY USAGE LIMIT

 14868  3A14  VERSION

 14869  3A15  TYPE

 14870  3A16  LANGDRIVER

 14871  3A17  FILL FACTOR

 14872  3A18  BLOCK SIZE

 14873  3A19  LOCKPROTOCOL

 14874  3A1A  LEVEL

 14875  3A1B  DRIVER FLAGS

 14878  3A1E  MEMO FILE BLOCK SIZE

 14879  3A1F  MDX BLOCK SIZE

 14888  3A28  INIT

 14889  3A29  DB CREATE

 14890  3A2A  DB OPEN

 14891  3A2B  TABLE CREATE

 14892  3A2C  TABLE OPEN

 14898  3A32  DB INFO

 14908  3A3C  TYPE

 14909  3A3D  PATH

 14910  3A3E  DEFAULT DRIVER

 14918  3A46  INIT

 14919  3A47  TYPE

 14920  3A48  STANDARD

 14921  3A49  TRUE

 14922  3A4A  FALSE

 14923  3A4B  OPEN MODE

 14924  3A4C  READ/WRITE

 14925  3A4D  READ ONLY

 14926  3A4E  SHARE MODE

 14927  3A4F  EXCLUSIVE

 14928  3A50  SHARED

 14929  3A51  USER NAME

 14930  3A52  SERVER NAME

 14931  3A53  DATABASE NAME

 14932  3A54  SCHEMA CACHE SIZE

 14933  3A55  STRICTINTEGRTY

 14938  3A5A  ORACLE

 14939  3A5B  1.0

 14940  3A5C  SERVER

 14941  3A5D  NET PROTOCOL

 14942  3A5E  DECNET

 14943  3A5F  NETBIOS

 14944  3A60  NAMED PIPES

 14945  3A61  SPX/IPX

 14946  3A62  TCP/IP

 14947  3A63  3270

 14948  3A64  VINES

 14949  3A65  APPC

 14950  3A66  ASYNC

 14958  3A6E  SYBASE

 14959  3A6F  1.0

 14960  3A70  SERVER

 14961  3A71  BLOB EDIT LOGGING

 14962  3A72  CONNECT TIMEOUT

 14963  3A73  TIMEOUT

 14964  3A74  DATE MODE

 14965  3A75  DATE SEPARATOR

 14966  3A76  DECIMAL SEPARATOR

 14968  3A78  INTRBASE

 14969  3A79  1.0

 14970  3A7A  SERVER

 14978  3A82  FORMATS

 14979  3A83  DATE

 14980  3A84  TIME

 14981  3A85  NUMBER

 14988  3A8C  SEPARATOR

 14989  3A8D  MODE

 14990  3A8E  FOURDIGITYEAR

 14991  3A8F  YEARBIASED

 14992  3A90  LEADINGZEROM

 14993  3A91  LEADINGZEROD

 14994  3A92  TWELVEHOUR

 14995  3A93  AMSTRING

 14996  3A94  PMSTRING

 14997  3A95  SECONDS

 14998  3A96  MILSECONDS

 15008  3AA0  DECIMALSEPARATOR

 15009  3AA1  THOUSANDSEPARATOR

 15010  3AA2  DECIMALDIGITS

 15011  3AA3  LEADINGZERON

 15013  3AA5  ascii

 15014  3AA6  DB437US0

 15018  3AAA  /

 15019  3AAB  0

 15020  3AAC  FALSE

 15021  3AAD  TRUE

 15022  3AAE  TRUE

 15023  3AAF  TRUE

 15024  3AB0  TRUE

 15025  3AB1  AM

 15026  3AB2  PM

 15027  3AB3  TRUE

 15028  3AB4  FALSE

 15029  3AB5  .

 15030  3AB6  ,

 15031  3AB7  TRUE

 15873  3E01  Wrong driver name.

 15874  3E02  Wrong system version.

 15875  3E03  Wrong driver version.

 15876  3E04  Wrong driver type.

 15877  3E05  Cannot load driver.

 15878  3E06  Cannot load language driver.

 15879  3E07  Vendor initialization failed.

 16129  3F01  Query By Example

 16130  3F02  SQL Generator

 16131  3F03  IDAPI

 16132  3F04  Lock Manager

 16133  3F05  SQL Driver

 16134  3F06  IDAPI Services

 16135  3F07  dBASE Driver

 16138  3F0A  Token

 16140  3F0C  Table

 16141  3F0D  Field

 16142  3F0E  Image

 16143  3F0F  User

 16144  3F10  File

 16145  3F11  Index

 16146  3F12  Directory

 16147  3F13  Key

 16148  3F14  Alias

 16149  3F15  Drive

 16150  3F16  Server error

 16151  3F17  Server message

 16152  3F18  Line Number

 16153  3F19  Capability

 16154  3F1A  Limit

 16239  3F6F

{ ErrList - Copyright 1995 Robert Arnson }

program ErrList;

uses DbiTypes, DbiProcs, DbiErrs, SysUtils;

var

  Category: byte;

  Code: byte;

  ResultCode: word;

  ErrorString: array[0..DBIMAXMSGLEN + 1] of char;

  Output: text;

  OutString: string;

begin

  DbiInit(nil);

  Assign(Output, 'ErrList.Txt');

  Rewrite(Output);

  for Category := ERRCAT_NONE to ERRCAT_RC do

    for Code := 0 to 255 do

    begin

      ResultCode := (Category shl 8) + Code;

      DbiGetErrorString(ResultCode, ErrorString);

      if StrLen(ErrorString) > 0 then

      begin

        OutString := Format('%6d  %0.4x  %s', [ResultCode, ResultCode, ErrorString]);

        WriteLn(Output, OutString);

      end;

    end;

  DbiExit;

end.

{This code came from Lloyd's help file!}


Delphi-DBF-Index?

#1000.BDE	From: koterski@genghis (Steve Koterski)

KeithPower wrote:

: I am a xBase type - Can anyone tell me if and how Delphi supports the

: following:

: DBF

: DBF Memo - If so what type? DBT/FPT Blob?

: Indexes  - If so what types NDX/MDX/CDX etc etc

: If indexes are supported are conditional ones allowed also?

: Does it have a similar Clipper/VO function to fieldget()/Fieldput()

Delphi and the Database Desktop (DBD) support dBASE memo files only.

They support the text memo as well as the binary BLOB field.

Indexes supported by Delphi/DBD are limited to dBASE indexes (for

dBASE tables, anyway). Further, They must be of the maintained type (MDX).

Non-maintained indexes (NDX) are not supported.

Delphi/DBD support the creation and use of conditional (dBASE) indexes.

There are a number of methods equivalent to the Clipper FieldGet() and

FieldPut() functions. However, in most cases (especially true for the

stock, data-aware components), this effect is automatic. But to account

for those situations where this functionality may be necessary, there

are means to cause this same effect programmatically. A good example of

this would be a situation where data is being accessed by calling the

Borland Database Engine (BDE) API functions directly, rather than by

the inherent Delphi data-aware objects.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

From: edgrant@ix.netcom.com (Ed Grant)

[snip]

  I bought Delphi thinking that I'd be able to access my FoxPro 2.5 .DBF

(with .CDX indexes) and .FPT (memos).  Are you saying I can't?  Do I

have to use ODBC drivers?  How about Microsoft ACCESS databases?


Paradox Table over a Network

#1001.BDE	From: koterski@genghis (Steve Koterski)

Wilhelm Sarasalo (pacsoft@netcom.com) wrote:

: Trying to connect to a Paradox table on a network drive gives me:

: "Unable to Open table"

: "Not Initialized for accessing network files"

: "Table H:\....."

: Page 11 on the database desktop users guide says that this should

: work as long as I configure BDE to find pdxusrs.net in the proper

: place.

: IDAPI says H:\ just like the ODAPI for Paradox for Win 4.5 which

: works just fine with H:\ drive.

: IDAPI and the database desktop works just fine with local tables.

There are two areas in the BDE (Borland Database Engine) configuration

that need to be properly set for this to work. The first is designating

the Paradox network file. This is done (in the BDE configuration utility

BDECFG.EXE) in the Drivers tab page, with the Paradox driver selected.

The NET DIR setting must be set to point to the location of an existing

.NET file or where a new such file is to be created. The second area is

setting up an alias to point to the location where the Paradox tables

reside (or will reside). This is done on the Aliases tab page of the

BDE configuration utility, specifically the PATH setting.

If these two areas are properly accounted for and the correct values

entered, you should be able to access a Paradox table located on a

network drive with no problem. Since you have indicated you have set

these settings and are still having a problem, I pose the following

questions for more information on the problem:

1. What network directory priviledges does this user have in the

   directory that will contain the .NET file? Where the Paradox tables

   reside?

2. Does the .NET file already exist prior to executing the operation that

   results in the error? If not, does one get created after the operatiuon

   fails?

3. Try copying one of the sample Paradox tables to a location where the

   user has full directory priviledges, adjust the settings in the BDE

   configuration utility to reflect this location, and attempt the same

   operation with this new table. Does the error occur?

4. Your article seems to imply you have more than one instance of IDAPI

   accessible to this computer (one for Paradox and one for Delphi). Is

   this the case? If so, which appears in the DOS PATH? If they both do,

   try putting the Delphi IDAPI directory first in the PATH statement.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


Delphi and Btrieve

#1002.BDE	From: koterski@genghis (Steve Koterski)

Jason Sweitzer (sweitzja@nando.net) wrote:

: Anybody know how to access Btrieve tables from Delphi?

You need to use a vendor-supplied ODBC driver, the hook to which will

be configured in the BDE configuration utility.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

From: nik@ess.niaid.pc.niaid.nih.gov (Nik Hughes)

In article <3k4l3l$f7j@druid.borland.com> koterski@genghis (Steve Koterski)

writes:

>From: koterski@genghis (Steve Koterski)

>Subject: Re: Delphi and Btrieve

>Date: 14 Mar 1995 17:51:49 GMT

>Jason Sweitzer (sweitzja@nando.net) wrote:

>: Anybody know how to access Btrieve tables from Delphi?

>You need to use a vendor-supplied ODBC driver, the hook to which will

>be configured in the BDE configuration utility.

But you won't like it! Access is VERY slow! Another programmer here had a line

on someone who was developing a better driver, but apparently that project got

cancelled. I've managed to access my Btrieve files from Delphi using the

existing drivers, but found it easier to dump the Btrieve files to ASCII and

then do an ASCII import into Paradox.

On the other hand. If you really are going to use Btrieve tables from Delphi,

you will need to build DDFs (Data Definition Files) to tell the driver what

your file layout is. These DDFs are Btrieve files that are used/supplied by

XQL (Novell's Btrieve SQL package). You have to use these external definition

files because Btrieve does not store any information about fields internally.

If you can get access to XQL, you are home free. If not, how good is your

programming with Btrieve?


Access 2.0 db and Delphi

#1003.BDE	From: rm_savard@pnl.gov (Rodney M. Savard)

I'd like to use an Access 2.0 database in a Delphi project.  Could someone

give me a rundown on some of the steps to get me started?  I've tried

several things and have gotten data controls to be able to see the

database, but I'm not sure if I'm doing it correctly.

I'd appreciate some advice on this subject.  Thanks!

--

Rodney M. Savard                                        rm_savard@pnl.gov

Kennewick, Tri-Cities, WA                                       Get NTed!

From: memorex@cats.ucsc.edu (Mathew Gyokers Eliot)

        Go into bdecfg, declare an alias that points to your odbc

access driver. Put the alias into teh "database" prop's of any

vcl that uses a database prop.

--

Beavis kicks ASS! He KICKS 'em! Kicks, KICKS!  He rules, he RULES, RULES!!

From: rm_savard@pnl.gov (Rodney M. Savard)

In article <3k5pbi$nl@darkstar.UCSC.EDU>, memorex@cats.ucsc.edu says...

>        Go into bdecfg, declare an alias that points to your odbc

>access driver. Put the alias into teh "database" prop's of any

>vcl that uses a database prop.

OK, that's pretty much what I did, but how do you suppress the "Select

target database" dialog?

Also, in VB you could do all databasing by code instead of using

data-aware controls.  Can you do the same in Delphi?

--

Rodney M. Savard                                        rm_savard@pnl.gov

Kennewick, Tri-Cities, WA                                       Get NTed!

From: koterski@genghis (Steve Koterski)

Rodney M. Savard (rm_savard@pnl.gov) wrote:

[...]

: OK, that's pretty much what I did, but how do you suppress the "Select

: target database" dialog?

Run the ODBC icon in Control Panel. It will list all of the ODBC Data

Sources you have defined. When defining a Data Source, one of the options

is to select a database. This is then passed down through the Borland

Database Engine (BDE) to the app.

: Also, in VB you could do all databasing by code instead of using

: data-aware controls.  Can you do the same in Delphi?

You can do all of the database and table set-up done through the visual

design surface programmatically. Your first step would be creating an

instance of TDatabase. You don't need to use this component when doing

database operations in the visual design surface, this is done for you.

But when doing this programmatically, this component is the starting

point.

To see what needs to be done, look up the TDatabase component in the

help file or just drop one on a Form and look at the associated properties.

All of them are fairly intuitive.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

From: <Unknown> (test)

In article <3kd9br$d1c@pipe2.pipeline.com>, mwj@pipeline.com (Jin Mai) says:

>I will write a database application wihich will be used by people with

>little

>or no Windows experience. If I write my application in Delphi and database

>in Access, users will have to run ODBC setup from control menu. Is there

>anyway to automate the ODBC setup without user interaction.

>Basically what I what is to automate database setup for users.

>--

>Jin Mai        mwj@pipeline.com

Just need to add some stuff to odbc.ini and odbcinst.ini.  Run the setup

on your machine, see what was added, the all you have to do is add it to the

two ini files when you install the database.  I am doing this using ODBC

with an Access 2.0 database and Microsoft Wordbasic (automating a form).

E-mail me if you want more specifics or have any questions.

Jon Peccarelli

jonpecc@csd.uwm.edu

From: mwj@pipeline.com (Jin Mai)

In comp.lang.pascal koterski@genghis (Steve Koterski) said:

>Run the ODBC icon in Control Panel. It will list all of the ODBC Data

Sources

>you have defined. When defining a Data Source, one of the options is to

select

>a database. This is then passed down through the Borland Database Engine

(BDE)

>to the app.

I almost pick up Delphi today until last minute I realized the ODBC setup.

I will write a database application wihich will be used by people with

little

or no Windows experience. If I write my application in Delphi and database

in Access, users will have to run ODBC setup from control menu. Is there

anyway to automate the ODBC setup without user interaction.

Basically what I what is to automate database setup for users.

 Also, If I use the database  enigne comes with Delphi, what kind of

database

does the DB engine support? Do I need extra tools to setup and admin

database.

--

Jin Mai        mwj@pipeline.com


Can Delphi read Foxpro dbs

#1004.BDE	From: Steve Teixeira <steixeir@borland.com>

pts@bullhead.adp.unc.edu wrote:

>

> I am one looking into the transition from VB to Delphi.  I am waiting on

> my copy of delphi to come in now but hope to get some insight.

> Right now we have a very large VB app that accesses quite a few Foxpro

> databases.  Will the regular Delphi provide a way to access these databases?

> In VB for Foxpro and DBase it acesses the same dll(xbs110.dll) to read

> these databases.  So I hope or wish that Delphi will look at Foxpro as

> just another Paradox or Dbase file.  We don't use ODBC as of yet so I

> can't justify the client server version YET!

> Any insight would be appreciated.

>

> have a nice day,

>

>        Thomas Sherrod

> email - pts@bullhead.adp.unc.edu

>

>

Foxpro and dBASE files are the same except for indeces and memos.  You'll

need to convert those to the dBASE flavor, and then you'll be able to

use the native dBASE driver, otherwise, you can go through ODBC.

        -Steve Teixeira

         steixeir@borland.com

From: koterski@genghis (Steve Koterski)

pts@bullhead.adp.unc.edu wrote:

[...]

: ...We don't use ODBC as of yet so I

: can't justify the client server version YET!

: Any insight would be appreciated.

In addition to the correct answer already provided by Steve T., I wanted

to mention that the ODBC hooks are present in _both_ the Desktop and

Enterprise (client-server) versions of Delphi. You have the capabilities

now of adding ODBC access. The only thing you would need to get beyond

what you have is a vendor supplied ODBC driver that would be used by the

Borland Database Engine (BDE) to access those FoxPro tables. Microsoft

should supply those. Try their FTP site:

   microsoft.com

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


Problem with Delphi exception EDBEditError

#1005.BDE	From: koterski@genghis (Steve Koterski)

ajd@nuc.ansto.gov.au wrote:

: Could someone tell me if I am using the EDBEditError exception correctly.

: I am using a MaskEdit component. If the input does not match the mask I

: wish to display my own messagebox. Part of my code is as shown below.

: procedure Dialog1.MaskEdit1Exit(...);

: begin

:   try

:     MaskEdit1.ValidateEdit;

:   except

:     on EDBEditError do

:       begin

:         { Display message }

:       end;

:   end;

: end;

: When the program is executed and the input does not match the mask,

: a default message is displayed but my code is never executed. If anyone

: could tell me why this does not work, I would be very thankful.

Do you have the Break On Exception setting set to True? See the menu

option Options|Environment, and look on the Preferences tab page. If this

is set to True, a Delphi exception error box will appear before or instead

of your exception handling dialog. (This is deliberate, for debugging

purposes.)

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


DB format to use?

#1006.BDE	From: koterski@genghis (Steve Koterski)

Magnus Gaefvert (f90mg@efd.lth.se) wrote:

: QUESTION: Which BDE database format is to prefer?

: I'm about to develope a database multi user application with Delphi using

: the BDE. My question is what database format should I use? Are there any

: significant differences between the DBase format compared to Paradox?

There are some fundamental differences between the dBASE and Paradox file

formats, mostly differences between data types. Numeric values are stored

differently in Paradox (as doubles) than in dBASE (stored as text, the

size of the field as defined in the structure). Paradox tables also

support password protection at the table level, dBASE tables do not.

Paradox indexes can enforce normalization, forcing values entered into

a field that is the basis of a unique index to be a unique value. In

dBASE, the primary purposes of indexes is the display order of fields

and (in the case of conditional and unique indexes) to suppress the

display of some records. With dBASE tables, referential integrity must

be handled programmatically.

: It seems local Interbase cannot be used for multi user applications. There

: is no data sharing with other apps, so I don't have to think about that.

The primary purpose of the Local InterBase supplied with Delphi is to

act as a surrogate client-server environment. This allows a developer

to create client server applications without actually being attached to

an SQL server back-end. Such applications are easily migrated by changing

the aliases referred to in the BDE configuration and either copying the

table files to the server back-end or creating them anew.

Using Local InterBase in an on-going manner is a secondary capability. It

can be done, but as you indicated, it does not have multi-user capabilities.

The intent there, of course, is that an application developed with Local

InterBase and Delphi will eventually be migrated to a true client-server

environment.

: Maybe : in the future I will have to rewrite the application to use a

: database server, if either format makes this step easier, please tell.

: From what I've seen in the manuals these formats handle indexing quite

: different. Which method is to prefer? I guess this makes SQL statements

: look different. Which format makes the SQL statements resemble ANSI92 SQL

: the most?

You can use SQL to access or manipulate data from local tables or tables

located on an SQL server back-end. Differences in needed syntax will for

the most part be related to the platform (local versus client-server),

not to specifics of the table. That is, if you have two tables, one

local and one on a server, and both have eseentially the same structure,

field/column names, and field/column data types, the SQL commands needed

to access or manipulate the data in the two tables will be pretty much

the same. The differences will come in using features not available in

local tables, such as stored procedures, triggers, database security,

etc.

Assuming that you do not take advantage of these advanced features, you

will have the option of migrating data from local tables to tables on

a server, with little or no changes to the application. The Database

Desktop allows for the migration of data between the various, supported

table types. Changes in the BDE configuration, aliases to point to the

new tables, would be needed. But if the table names and field/column

names are the same as in the local tables, most data access designed around

the local tables will work as-is on the server tables.

: Are there any table sharing or networkning issues that differ between the

: formats?

Between dBASE and Paradox tables, Paradox tables use a couple network

specific files to track multi-user operations. These are created at run-

time, if they do not previously exist.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

From: mac@zeus.hsrc.ac.za (Malcolm Coulter)

Subject: Re: DELPHI --- DB format to use?

Date: Wed, 22 Mar 1995 09:12:39 GMT

In article <3kn0up$604@druid.borland.com> koterski@genghis (Steve Koterski)

writes:

>Magnus Gaefvert (f90mg@efd.lth.se) wrote:

>: QUESTION: Which BDE database format is to prefer?

>: I'm about to develope a database multi user application with Delphi using

>: the BDE. My question is what database format should I use? Are there any

>: significant differences between the DBase format compared to Paradox?

[cut]

>: It seems local Interbase cannot be used for multi user applications. There

>: is no data sharing with other apps, so I don't have to think about that.

>The primary purpose of the Local InterBase supplied with Delphi is to

>act as a surrogate client-server environment. This allows a developer

>to create client server applications without actually being attached to

>an SQL server back-end. Such applications are easily migrated by changing

>the aliases referred to in the BDE configuration and either copying the

>table files to the server back-end or creating them anew.

>Using Local InterBase in an on-going manner is a secondary capability. It

>can be done, but as you indicated, it does not have multi-user capabilities.

>The intent there, of course, is that an application developed with Local

>InterBase and Delphi will eventually be migrated to a true client-server

>environment.

-----------------------------------------------------------------------

One could add multi-user capability to the local InterBase server by using

CAS (Client-agent-server) networking instead of the more direct CS

(client-server) method. But it hardly seems worth while as the agent would not

only have to look like InterBase to the clients, but would have to do all the

housekeeping associated with multi-user access. I have used CAS to access

simple databases on non-server PCs and to implement store-and-forward

messaging, but rather use the real thing where it is possible. Am I right in

remembering that Borland has worked out a low cost licensing scheme for

InterBase on small networks and workgroup servers?


dBASEwin->delphi-Index (string) problems

#1007.BDE	From: jleon@ix.netcom.com (John Leon)

In <3kvn1e$1up@newsbf02.news.aol.com> timeoilmis@aol.com (TimeOilMIS)

writes:

>

>Okay, here's a question for everyone.

>     I am trying to create a form in Delphi that will access a dBASE

>table. What I am trying to do is to get a value from the user, and use

>that value to do a FindKey, then I want to restrict the records

displayed

>with SetRange, then I want to use a different index. the different

index

>is a complex index based on the first two fields in the table. Both are

>character strings, the first of 6 characters and the last of three

>characters. The second indexed field has values that range from 3 to

999,

>but are character strings, not numbers.

>     It all works fine until I try to do the SetRange, as I have been

>unable to come up with a way to represent the complex index values as

>lower and upper bounds. No matter what I have tried, I am getting an

index

>falls out of range error.

>     BTW, switching the indexname property seems to override any

previous

>setRange that has been applied. Is this the correct behavior?

>     Any thoughts on this subject would be greatly appreciated.

>

>TIA

>

>Brad Miller

>TimeOilMIS@aol.com

>

As best as I can determine, the SetRange functions work on index keys,

and it appears that index *expressions* are NOT index keys.  It's a

problem.  You'll probably find the best help with questions like this on

Compuserve's Delphi forum, where the message traffic is VERY high, but

where there are countless Delphi adepts hanging out.

--

* John C. Leon, VP

* Capital Markets Technology

* Texas Commerce Bank, Houston, TX

* (a subsidiary of Chemical Banking Corp.)

* jleon@ix.netcom.com


DELPHI & Borland Database Engine

#1008.BDE	From: Steve Teixeira <steixeir@borland.com>

unified@clark.net (Charles Bouknight) wrote:

>

> I'm considering purchasing Delphi (as well as a new 850mb hard drive!).

>

> Can someone shine some light on the Borland Database Engine.  Someone

> mentioned that this is a runtime engine which must be distributed with

> your Delphi program.  Can't Delphi itself be used with BDE to develope a

> pure standalone EXE file that can access Dbase, Paradox, etc. files?

>

> I thought I was a loyal Borland customer, but I have yet to receive

> anything from Borland about Delphi, even in the package of information I

> requested and received from them on their products.

Delphi uses the BDE to facilitate database access.  If you distribute a db

application, you need to redistribute the 2 BDE diskettes.

Sorry you haven't gotten the Delphi info you've been looking for.  The best

place

to go right now is http://www.borland.com for Delphi info.

        -Steve Teixeira

         steixeir@borland.com


Can Delphi Use Paradox Engine?

#1009.BDE	From: koterski@genghis (Steve Koterski)

Sergio Olivas (olivas@deltanet.com) wrote:

: We have a program that uses the Paradox Engine for Dos. That

: program interfaces with tables also used in Windows, using the

: Paradox Engine for Windows (pxengwin.dll).

: Assuming that I don't want to use the Borland BDE (yes, though I

: Know support is built in, but this is part of a larger software

: package), Can the paradox engine, using regular pxengine Calls, be

: made to work with Delphi? Has anyone actually tried this yet?

In this context, you are just looking at another DLL containing functions

and procedures you will call from your application. While the functionality

of the BDE is inherent in database and table operations involving data-

aware components, you can instead call the BDE's functions directly,

essentially doing what Delphi does for you the hard way.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


Can I ship only part of the BDE?

#1010.BDE	From: Steve Teixeira <steixeir@borland.com>

bill.lenson@marcam.com (Bill Lenson) wrote:

>

>

> I read somewhere that if I want to ship any DB tool developed with Delphi

> and using the Borland Database Engine, I need to ship ALL of the BDE.  Is

> this true?!

>

> What if I want to write a small tool that uses the Paradox

> engine of the BDE - do I have to ship the dBase, ODBC, etc, drivers too?

> I don't think I can explain to Compuserve of BBS users that a little

> freeware tool will cost them big bucks because they have to download

> a meg or more worth of zipped files, just to get my utility.

>

> Am I right?

>

You have to ship the *whole* BDE.  I know it's a bummer, but there is a good

reason:

If your customer already has a BDE product like Paradox, dBASE, Quattro,

or BDE 2.0, and then installs your program with only part of the BDE, then

1/2 of his BDE will be old and 1/2 will be new.  Then, say, the user goes to

access Paradox and Wham! it doesn't work...

        -Steve Teixeira

         steixeir@borland.com

From: koterski@genghis (Steve Koterski)

Bill Lenson (bill.lenson@marcam.com) wrote:

: I read somewhere that if I want to ship any DB tool developed with Delphi

: and using the Borland Database Engine, I need to ship ALL of the BDE.  Is

: this true?!

: What if I want to write a small tool that uses the Paradox

: engine of the BDE - do I have to ship the dBase, ODBC, etc, drivers too?

: I don't think I can explain to Compuserve of BBS users that a little

: freeware tool will cost them big bucks because they have to download

: a meg or more worth of zipped files, just to get my utility.

: Am I right?

You can distribute the BDE files in their entirety with your app, or

only those that pertain to accessing a specific flavor of tables. See the

text file DEPLOY.TXT in the Delphi home directory. It describes this

process, including which files you need for which type database access and

which for all types.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

From: koterski@genghis (Steve Koterski)

Steve Koterski (koterski@genghis) wrote:

[...]

: You can distribute the BDE files in their entirety with your app, or

: only those that pertain to accessing a specific flavor of tables. See the

: text file DEPLOY.TXT in the Delphi home directory. It describes this

: process, including which files you need for which type database access and

: which for all types.

It has been pointed out to me that this information (above) is technically

incorrect. A more thorough reading of the file DEPLOT.TXT will show that

the requirement is that the BDE be installed in its entirety, and by using

the BDE installation routine.

It is possible, however, to delete unneeded files *after* this installation

process using the list of files and their purposes in DEPLOY.TXT. I

apologize if my previous response caused any undue confusion in this

matter, and hope that this clears up any such confusion.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

From: Steve Teixeira <steixeir@borland.com>

mwj@nyc.pipeline.com (Jin Mai) wrote:

>

> Please correct me If I misunderstood Borland's distribution policy.

> I will use Delphi to develop a paradox database app. Do I HAVE to

> ship every files in the two BDE disks with all ODBC, DBabse and

> SQL link drivers? If that is the case, why would someone in the

> news group promote BDE better MS Jet DB engine?

>

Yes if you create an application that accesses tables through ODBC, you need

to ship the BDE (2 disks) and the necessary ODBC driver.  You only need to

ship the SQL links drivers for the servers you connect to, however, why would

you need to ship both the SQL links drivers *and* an ODBC driver? Also,

I'm not sure what you mean by "DBabse" driver (I assume you're referring to

dBASE), since that functionality is built into the BDE.

Why use BDE of Jet? The primary reasons are because BDE supports a variety

of SQL and non-SQL databases natively (in addition to ODBC), and because the

native drivers are generally faster than Jet.  Also, BDE is easily scalable

between local tables and SQL-servers (Just by changing the db alias),

whereas Jet is not. The biggest reason, though, is because Delphi uses the

BDE and VB uses Jet, and this is the comp.lang.pascal group. :)

        -Steve Teixeira

         steixeir@borland.com


Creating InterBase Tables using the Desktop

#1011.BDE	From: koterski@genghis (Steve Koterski)

as360114@orion.yorku.ca wrote:

: Excuse my "inexperiece", but I question that may look simple:

: I am trying to create tables using the "Database Desktop" tool on the local

: InterBase database. Whenever I try to do that, and select opening a new

table,

: the system asks me to save as a file. I guess that this should be fine for a

: DBase or a Paradox database, but what should I do with an InterBase

database?

: In simple terms: What am I doing wrong here?

In the DataBase Desktop (DBD), after selecting the File|New|Table, you

should be presented with a Table Type dialog. In this dialog there is a

listbox of possible table types. "INTERBASE" should be in that listbox

(assuming you have not removed the InterBase driver from the Borland

Database Engine (BDE) configuration). This sets the new table's type.

If INTERBASE does not appear in this list, run the BDE configuration

routine (BDECFG.EXE, found in the IDAPI directory) and double check

that InterBase is in the list of available drivers in the Driver Name

list on the Drivers tab page.

After defining the table and selecting to save, in the Save Table As

dialog, you will be able to designate what database this new table is

to be part of. The New File Name entry sets the table name and the

Drive (or Alias) sets the database (using aliases created in the BDE

configuration).

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


Two forms accessing the same table

#1012.BDE	From: koterski@genghis (Steve Koterski)

Earache (earache@primenet.com) wrote:

: Forgive my ignorance, but I'm new to programming DB apps.

: What I have is an MDI application where I want to edit and update a

: DBFile, but I also need to create completely new versions of the database

: for new MDIchilds that are created.  Is there an easy way of going about

: this or should I stick with record data types?

Given two Forms, each with a TTable component connected to the same table,

the cursors for each will be distinct. That is the current record in each

TTable are each independent of that in the other TTable.

In your MDI situation, you could put a TTable on the base TForm from

wwhich all these MDI Child Forms will be derived, without assigning it

to a table at design-time. Then, at run-time as each MDI Child Form is

generated, it will inherit the empty TTable component from the base

TForm, and you can set the DatabaseName and TableName properties at that

time. Alternatively, you could put a TDatabase component on the MDI Frame

Form if all the tables to be used are in the same database. In this case,

when the MDI Child Forms are created, you associate the TTable components

with that TDatabase component.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


Best way to set range, filter...

#1013.BDE	From: koterski@genghis (Steve Koterski)

TimeOilMIS (timeoilmis@aol.com) wrote:

: Here's another newbie question. I am making a dialog box for entering a

: value, which I then want to use as a filter for the form that calls the

: dialog. In Paradox or dBASE, there are numerous ways to do this, (through

: quries and tilde variables, set ranges and set filters). In Delphi, all I

: can find are some fairly cumbersome SetStartRange, SetEndRange, etc.,

: calls. I just want to use a Delphi form as a lookup for a database record.

: Whats the best way to accomplish this?

I am sure that there are innumerable ways to address this. Here's one.

If, on the dialog Form, you only add a TDataSource component and no

corresponding TTable, you can connect that TDataSource component to the

TTable on the calling Form. This connection would occur at run-time by

setting the DataSet property of the TDataSource to the first Form's

TTable. This also requires making the calling Form accessible to the

called, dialog Form in a Uses section in the dialog Forms Implementation\

section (to avoid recursive Uses). This would suffice if you wanted to

see the same records in the dialog's Listbox as available in the calling

Form (i.e., non-unique if that is the case in the calling Form).

Alternatively, you might use a TQuery in the calling Form instead of the

current TTable. Initially, the SQL property would contain an SQL statement

that displays all records, but after execution you would clear that SQL

property and replace it with one that include a filtering value (see the

Params property).

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


Anyone got an interbase app working??

#1014.BDE	From: koterski@genghis (Steve Koterski)

Bryan Zarnett (vdata@inforamp.net) wrote:

: Trying to put my app from dbase to an interbase app..and things go bezerk.

I

: created my interbase database using ISQL, even set up an Alias for it, but

: when I try to connect a TQuery and TDataset or TDatabase object things go

: bezerk...User Name/Password not defined, cursor error,etc, etc,etc...is

there

: a clear cut way to handle interbase databases in Delphi?

Are you using the user name SYSDBA and password MASTERKEY? If not (i.e.,

you are using a user name and password of your own creation), have you

run the Server Manager utility (IBMGR.EXE, in IBLOCAL\BIN) to set up

this new user name and password?

To test this, try using the SYSDBA/MASTERKEY combination with this app.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


SQL and Paradox

#1015.BDE	From: koterski@genghis (Steve Koterski)

Ron Hula (nrgmaker@delphi.com) wrote:

:

: I'm trying to execute a simple SQL statement with an aggregate:

:

: SELECT Name,SUM(Hours)

: FROM "PROJ.DB"

: GROUP BY NAME

:

: As long as I have the SUM or the Group by, it comes back

: and says "Capability not supported".

:

: I don't have the InterBase server loaded..is that my only problem.

: Isn't there supposed to be a subset of SQL for local use.

I am assuming from the cited code that the table involved is a Paradox

table (i.e., "PROJ.DB"). If that is the case, you do not need anything

to do with Local InterBase for these purposes, and yes you can issue

SQL commands against such local tables.

To test your situation, I created a Paradox 5.0 table, containing two

fields: Name and Hours (Alpha and Number, respectively). The table was

named PROJ.DB to follow your example. I did not create an index for

this table. I was able to successfully perform the operation described

using local SQL, producing a summarization of the Hours field, with

the data set grouped by the Name field. The SQL code used was:

   SELECT PROJ."Name", sum(PROJ."Hours")

   FROM "PROJ.DB" PROJ

   GROUP BY PROJ."Name"

Try this syntax and see if it provides the results you need.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


Delphi-Paradox: table password

#1016.BDE	From: koterski@genghis (Steve Koterski)

Jin Mai (mwj@nyc.pipeline.com) wrote:

:

: I am trying to open the sample paradox tables in Delphi.

: The ODBC logon window prompt for a password for each

: paradox table. Someone please tell me the password or where

: can I find out the password for all the paradox tables?

Certain ODBC drivers do this, including the ReportSmith ODBC driver for

Paradox tables, included with Delphi. This dialog will appear even if

there is no password protection for the table. In your situation,

assuming there is indeed no password protection on the table (and there

shouldn't be on any of the sample Paradox tables), just click the OK

button in the login dialog to bypass this.

To accommodate this in an application, simply add a TDatabase component

to the Form, set its LoginPrompt property to False, and connect the

TTable component to this TDatabase.

But the question remains ... why bother with an ODBC connection to

Paradox tables at all. Native access is better and faster. Unless you

are doing this just to experiment with Delphi's ODBC hooks...

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

From: jleon@ix.netcom.com (John Leon)

In <3l24mb$f00@druid.borland.com> koterski@genghis (Steve Koterski)

writes:

>Certain ODBC drivers do this, including the ReportSmith ODBC driver for

>Paradox tables, included with Delphi. This dialog will appear even if

>there is no password protection for the table. In your situation,

>assuming there is indeed no password protection on the table (and there

>shouldn't be on any of the sample Paradox tables), just click the OK

>button in the login dialog to bypass this.

>

>To accommodate this in an application, simply add a TDatabase component

>to the Form, set its LoginPrompt property to False, and connect the

>TTable component to this TDatabase.

>

>But the question remains ... why bother with an ODBC connection to

>Paradox tables at all. Native access is better and faster. Unless you

>are doing this just to experiment with Delphi's ODBC hooks...

>

>--

>_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_

/_/

>_/ Steve Koterski               _/   The opinions expressed here are

 _/

>_/ koterski@borland.com         _/         exclusively my own

 _/

>_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_

/_/

>

Steve,

I've seen the BDE itself do this regularly.  I'm a victim to the same

problem myself.  Can't remember how I got rid of it, but I believe the

originator of the question just assumed it was an ODBC login prompt when

it was likely from the BDE.

--

* John C. Leon, VP

* Capital Markets Technology

* Texas Commerce Bank, Houston, TX

* (a subsidiary of Chemical Banking Corp.)

* jleon@ix.netcom.com

From: mwj@nyc.pipeline.com (Jin Mai)

In comp.lang.pascal jleon@ix.netcom.com (John Leon) said:

>In <3l24mb$f00@druid.borland.com> koterski@genghis (Steve Koterski)

writes:

>

>>Certain ODBC drivers do this, including the ReportSmith ODBC driver for

>>Paradox tables, included with Delphi. This dialog will appear even if

>>there is no password protection for the table. In your situation,

>>assuming there is indeed no password protection on the table (and there

>>shouldn't be on any of the sample Paradox tables), just click the OK

>>button in the login dialog to bypass this.

Again, let me state clear what I am trying to do. I am in MS Query.

I open a query, MS Query prompts with a list of ODBC sources.

I choose Paradox file ODBC drivers comes with Delphi. MS Query

prompts at list of sample paradox tables in Delphi\Demos\Data subdir.

I choose Items.db. A dialog box prompt password for Items.db. I click

OK without typing anying thing. The dialog disappear and return to the

list of paradox tables. It seems like I have to give a password for the

ITEMS.DB.

Does anyone KNOW the password for ITEMS.db?

--

Jin Mai        mwj@pipeline.com


Delphi-Access

#1017.BDE	From: koterski@genghis (Steve Koterski)

Jin Mai (mwj@nyc.pipeline.com) wrote:

:

: I have tried to use Access mdb in Delphi and failed.

: Access ODBC is setup to use in MS Query. Now, how

: do I use the same access ODBC driver for Delphi. What

: step do I have to follow to connect Delphi to Access mdb?

The first step is to set the driver up in the BDE configuration utility:

BDECFG.EXE, found in the IDAPI directory. There is a New ODBC button on

the Drivers tab page.

You should be using the version 2.0 Access ODBC driver as earlier drivers

had a number of features disabled.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


Query a Query

#1018.BDE	From: koterski@genghis (Steve Koterski)

Ron Hula (nrgmaker@delphi.com) wrote:

:

: How do you Query a Query?

:

: Have a Query that produces an intermediate result.

: How do you access that result from another Query?

: (i.e. what do you use in the FROM part of the SQL, ANSWER.DB? or what?)

How about a nested SELECT? By way of example, the following applies to

the Local InterBase table Employee, in the database Employee:

   SELECT EMPLOYEE.LastName, EMPLOYEE.Salary FROM EMPLOYEE

     WHERE EMPLOYEE.Salary = (SELECT MAX(EMPLOYEE.Salary) FROM EMPLOYEE

This nested SQL command can be used in a TQuery's SQL property. The two

SELECT statements use the same table, but you could just as well base the

two data queries on two different tables.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

From: cllee@slip.technet.sg

In article <5+8b-we.nrgmaker@delphi.com>, Ron Hula

<nrgmaker@delphi.com> says:

>

>How do you Query a Query?

>

You can't. Borland's IDAPI database engine (used in dBASE,

Paradox, QuattroPro for Windows, etc) does not allow queries

within queries. A classical example is

        SELECT * FROM ADDRESS WHERE (SELECT * FROM ADDRESS WHERE ;

                                     STATE = "CA")

The only workaround is to break such queries into separate

query statements. The other not so nice thing about this is

that no matter what you do, the IDAPI engine will generate a

ANSWER.DB/DBF file. This is unlike, say, FoxPro or Access

where the temporary files are taken care of by the engine.

Hope this helps.

Cheers!

3/26/95


Delphi --> MS SQL Server using ODBC ???

#1019.BDE	From: cllee@slip.technet.sg

Bonjour Jean-Claude,

In article <3l1n70$mgp@grasp.insa-lyon.fr>, jcberger@grasp.insa-lyon.fr

(Jean-Claude Berger) says:

>

>By the way, Paradox has a bug : forms don"t display datetime and smalldatime

>SQL Server columns when accessing a table via ODBC (Paradox does display

>them when you don't use a form). Does Delphi has the same problem ?

>

I don't think this is a bug. The issue is that MS SQL Server's

timedate format is approximated by Paradox as best as it could

to its own native format.

>

>At last, any search with Paradox, SQL Link and SQL Server is incredibly slow.

>What about Delphi ?

>

Je crois que oui. Paradox and dBASE for Windows are interpretive

in nature. Look at Borland's own Delphi literature and you'll know

what I mean.

Cheers!

3/26/95


DELPHI -> Addindex broken?

#1020.BDE	From: koterski@genghis (Steve Koterski)

an229125@anon.penet.fi wrote:

: The following piece of code causes a Database Engine Error which

: states that the index name must be specified, as you can see it

: is.

[...]

: procedure TStockLevl.CreateIndex;

: begin

: try

:   Begin

:       stock2.close;

:       stock2.AddIndex('NewIndex' , 'Code', [ixUnique]); <<<<<< error here

:        stock2.open;

:   end;

:   except

:      MessageDlg('Indexing Error', mtInformation, [mbOK] , 0);

:   end;

: end;

: end.

I tested this using a dBASE table and the ReportSmith ODBC driver for

dBASE tables, and was able to execute this code. It successfully created

the index and ordered the records by that index.

So, what table type is involved here? And, what ODBC driver are you using?

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


Creating Simple Databases

#1021.BDE	From: jtykal@mcs.com (Jim Tykal)

B Schlereth writes

> Hi,

> <...snip...>

> What I am looking for is a database library or object or control (or

something

> which I have called an engine) that gives you the ability to create,

> manipulate, sort, find, replace, etc. simple flat database records from

within

> a custom program.

> <...snip...>

Check out the Database Desktop app (which is included with Delphi) to

create your database.  Look at the examples in Chapter 2 of the Delphi

"Database Application Developer's Guide" for how to tie controls to your

data.  You can create controls to do everything you mentioned.

> Can I create a simple database in a program like Lotus Approach and then

> operate on the database file using Delphi.

>

If its as simple as you say, use the Database Desktop.

> Thanks for any info or pointers.

>

> Barry.

--

----------------------------------------------------------------------

Jim Tykal, jtykal@mcs.com         http://www.mcs.net/~jtykal/home.html

----------------------------------------------------------------------

Swiss Bank and Decision Consultants help pay the bills, but they don't

always share my opinions.  Any expressed here are mine and mine alone.


Delphi->dBASE complex index again

#1022.BDE	From: timeoilmis@aol.com (TimeOilMIS)

Hello again!

     Well, haven't gotten any responses yet on this one, so I thought I'd

put in a bit more info. I am basically trying to do a SetRange on a dBASE

complex index. Here's the deal:

                        Field Name         type

                           PROPNO          C     6

                           IDNUM              C     3

Indextag PI4Delph

PROPNO+IDNUM    (Unique and Maintained)

Example '03-150__3' where the underscore is a blank. IDNUM can range from

__1 to 999.

Propnum is retrieved from the user by way of an InputBox function call.

Value stored in string variable testvar

I use a different index first to search for the testvar value. If it is in

the table, i then set the IndexName of the table to PI4Delph. I then only

want to display those records with PROPNUM=testvar, but ordered by IDNUM.

All of the following have resulted in Index Out Of Range Errors.

Table1.SetRange([testvar,'  1'],[testvar,999])

Table1SetRange(Testvar+'  1',Testvar+'999')

etc.

QUESTION!--Is there any way to see what Delphi thinks the index values

look like? In other words what can I type into the Evaluate dialog box to

access whatever Delphi "thinks" an index is?

Any other thoughts?

Arrrgh!

Other than for this, I love this product!!!!

Brad Miller

TimeOilMIS

From: timeoilmis@aol.com (TimeOilMIS)

OK, I've solved it, (sort of). Here's the deal. I decided to avoid

SetRange and use the full SetRangeStart, SetRangeEnd, ApplyRange, motif.

then I decided to refer to the fields in the target table by name,

(function FieldsByName). Then I added, AsString to the mix.

Resulting in:

Table1.SetRangeStart;

Table1.FieldsByName('PROPNO').AsString:=testvar;

Table1.FieldsByName('IDNUM').AsString:='  1';

Table1.SetRangeEnd ;

Table1.FieldsByName('PROPNO').AsString:=testvar;

Table1.FieldsByName('IDNUM').AsString:='999';

Table1.ApplyRange;

Which works like a charm. It leaves me with some questions though. Such

as: Why is the AsString necessary as I am dealing with dBASE Character

fields. Is the reference to the field required? It would appear from what

I've seen in the docs I should be able to acces the index directly without

having to specifically reference the field. At least that's what it looks

like to me in all the discussion of how Delphi will use production

indicies by default. Also I do not know if it is possible to do a

multi-field index in a single SetRange. But as this is working, these are

less important.

Brad Miller

timeOilMIS@aol.com


Visible sort & restricting records?

#1023.BDE	From: koterski@genghis (Steve Koterski)

marwk@levels.unisa.edu.au wrote:

: Here is the scenario:

: I place a visible table object and query on the screen.

: COntrols are included.

: I place buttons on the screen to allow the user to choose a sort order

: based on the field specified on the button.

: There is an edit-field which is used by the user to enter the value

: of a field with which to restrict the records in the table.

: What I intend doing is rewriting the SQL code.

: 1. is this the best way of doing it?

The intended method would be to call the SQL property's various methods

to first clear any existing code in the SQL property, and then fill it

with the new code.

: 2. what code should be used?

The Clear method of the SQL property will clear any code that currently

exists in the SQL property. The Add() function will allow you to add one

or more lines to the SQL property (which is of type TString). Here's an

example:

   Query1.Close;

   Query1.SQL.Clear;

   Query1.SQL.Add('SELECT * FROM MyTable');

   Query1.SQL.Add('ORDER BY Name');

   Query1.Open;

For more on this, see Chapter 5 ("Using SQL in applications") of the

Database Application Developer's Guide. Especially, look at the examples

on page 118.

: 3. how can I allow for the no restrictions at all?

Can you rephrase the question?

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


TQuery Question

#1024.BDE	From: koterski@genghis (Steve Koterski)

Thomas McKeon (TMcKeon@ix.netcom.com) wrote:

: Hi Everyone;

: I just got Delphi and it looks great. I could use a little help with a

: TQuery though.

: I want to create a program which will help users find Part Numbers using

: a key word type search on the Part Description. But I want to show only

: the records that have the key word (or string) in the description. I can

: do this with a dynamic query when I specify an exact match for a column

: value but not partial.

: Can I do this with a TQuery? If not, any suggestions would be

: appreciated. Thanks:)

This is very simple to do when you use the LIKE operator of the SELECT

command.

Assuming you already have (in the TQuery's SQL property) the necessary

SELECT command to show all records using the desired fields and only need

to add the WHERE clause, you can do this programmatically, taking (in this

example) the value from a TEdit component as the search value.

   Query1.Close;

   Query1.SQL.Add('WHERE TABLE."FIELD" LIKE ''%' + Edit1.Text + '%''');

   Query1.Open;

In this example, "TABLE" represents the table name and "FIELD" the field

in which the search is to be performed.

For more information on using SQL in applications, please see Chapter 5,

"Using SQL in applications," in the Database Application Developer's

Guide.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


DB Controls: Scrolling and Which Record

#1025.BDE	From: Steve Teixeira <steixeir@borland.com>

j-walter@tamu.edu (Dr. John P. Walter) wrote:

>

> Two questions, short and sweet:

>

> 1.  Why does the scroll  thumb in a DBGrid control not reflect the

> row's position in a database?  It is at the top at the first record,

> at the bottom when accessing the last record, and exactly

> midway in between for all other records.  Is there a

> porperty I can set?

Because to do so would require Delphi to keep track of how many records are in

the dataset at any given time.  Aside from the obvious impracticalities of

doing this with tables with a lot of read/write action going on, it can be

very slow and painful to get a record count of a dataset depending on the

database

back-end.

> 2. How can I find out which record (row) is the current record

> in a TTable?  I RTFM but can't find an answer to this (admit-

> tedly seemingly trivial) question.

I tried a couple of things, but I can't seem to find a way.  BTW, It's

generally considered

bad design to rely on record numbers in your programs (particularly if you

plan on ever

upsizing your application to Client/Server).

Hope that helps,

        -Steve Teixeira

         steixeir@borland.com


DELPHI Dislikes Changing Database Field Size

#1026.BDE	From: Steve Teixeira <steixeir@borland.com>

jtykal@mcs.com (Jim Tykal) wrote:

>

> Changing the length of an alphanumeric field in a Paradox data table

> (which is used by a Delphi app) causes Delphi to complain about the field

> being an "invalid type".  Changing the MaxLength property of the component

> which used this data didn't fix the problem.  Neither did exiting and

> restarting Delphi.  I had to remove the TTable component from my app, then

> recreate it to make this problem go away.  Is there another way to make

> Delphi "re-sync" with the format of the data tables?

I couldn't reproduce this.  These are the steps I used:

1. Put a TTable on a form along with a TDataSource and a TDBGrid to display

   the table.

2. Set TTable.Database and TTable.TableName to a Paradox table.

3. Set Active to True.

4. Set Active to False.

5. Go to DBD and expand one of the char fields from 24 to 30 chars.

6. Go to Delphi, and set TTable.Active to True.

Perhaps if you could come up with some steps, that would be helpful.

        -Steve Teixeira

         steixeir@borland.com


Query and live data sets (Views)

#1027.BDE	From: koterski@genghis (Steve Koterski)

Magnus Gaefvert (f90mg@efd.lth.se) wrote:

: Maybe I haven't got this right, but it seems to me that the tquery

: component is a little limited. Or maybe I should say that the

: local SQL supported by the BDE is somewhat limited. Consider an

: invoice form with multiple item rows. I.e. an one to many

: relation. It would be nice to be able to create a view displaying

: this relation, like ANSI 92 SQL's CREATE VIEW, giving a live data set

: as result with the user beeing able to edit data. This doesn't seem

: to be possible. The manuals tell me that this can be done with

: queries using a single table only. If so, will I have to code

: this behaviour myself, or is there some other way to go?

While it is true that when you link two tables through an SQL command

the resulting data set is read-only, it is still possible to dynamically

link the two tables such that both are editable. This is done through

linking with internal Delphi methods rather than an SQL command. This

process of creating a Master-Detail form is described in some detail in

Chapter 2, "Building a sample database application: MASTAPP", in the

Database Application Developer's Guide. Basically, the tables are

dynamically linked by representing each table with a TTable component and

then setting the MasterSource property in the Detail table to point to

the key field in the Master table. On execution, only those records that

match the key field value in the current record in the Master table

become visible for the Detail table, and -- most importantly -- the field

values from both tables are editable.

See the section entitled "Building a master-detail form" on page 24 of

the Database Application Developer's Guide for more details on this.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


Search the Data Base

#1028.BDE	From: koterski@genghis (Steve Koterski)

ShdwMstr (drglance@mindspring.com) wrote:

[...]

: O.k., so Delphi created all the hooks into the database for me.  Now, I want

: to create a search on the database via the field 'LastName' which out of 12

: field from 0 - 11, is number 1.  From here I want to type in the lastname in

: an edit box or whatever, click on a search button and have the all info

: pertaining to the last name I entered put into the TDBedit boxes.

: I have yet to find any info on how to do this in the manuals nor in the help

: files, however, several people have tried helping me, but I did not give all

: the information they needed for a better answer.  Well, here it is!:)

: It is a pretty straightforward app that delphi actually created itself to

: hook into the database.  The rest is up to me and I have no idea on how

: to do it!

Your search will likely require the use of the FindKey or GotoKey

procedures. These procedures take a parameter representing the search

value. This value may take the form of a literal value, a memory variable,

or the value of a control such as a TEdit component. Assuming a TEdit

component on the Form for entering the search value and a TButton (here

named Button1) for triggering the search, the code in the OnClick event

for that button might look like this:

   procedure TForm1.Button1Click(Sender: TObject);

   begin

     Table1.SetKey;

     Table1.FieldByName('LastName').AsString := Edit1.Text;

     Table1.GotoKey;

   end;

You can see this described and demonstrated in greater detail on page 72

of the Database Application Developer's Guide.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


How to detect an empty data set?

#1029.BDE	From: koterski@genghis (Steve Koterski)

Gary Cramblitt (garyc@clark.net) wrote:

: How does one detect when a query returns no records?  I tried

: attaching the following code to the AfterOpen event of the dataset,

: but it does not work:

:   procedure TRemindersForm.SelectAlarmsAfterOpen(DataSet: TDataset);

:   begin

:     if SelectAlarms.RecordCount <= 0 then

:       RemindersForm.Close;

:   end;

: The query is against a Paradox table.  After studying the online help

: quite a bit, I'm guessing that the basic problem is that the BDE

: returns _no dataset_ as opposed to an _empty dataset_ when the query

: selects no records.  This causes the RecordCount property to be

: "undefined"????  So how DO I detect that no records were selected?

One way is to check the Eof property of the TQuery. Typically, you would

do this in the TQuery's AfterOpen event, as in:

   TForm1.Query1AfterOpen(DataSet: TDataSet);

   begin

     if Query1.Eof then

       {True code}

     else

       {False code}

   end;

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


"Error creating cursor handle"

#1030.BDE	From: koterski@genghis (Steve Koterski)

Gary Cramblitt (garyc@clark.net) wrote:

: Can someone tell me what I am doing wrong?

: Start a new project.  Drop a TQuery component on the form.  Set the

: DatabaseName property to my database alias.  Enter the following in

: the SQL property

:   update Reminder

:   set AlarmAcknowledged = 'true

: Reminder is a simple Paradox table.  AlarmAcknowledged is a boolean

: field therein.  Now, I set the Active property to true and get

:   Error Stop: Error creating cursor handle.

: Does anyone else get this behaviour?  What am I doing wrong?

When using update queries, you cannot use the Open method or set the

Active property to True to invoke the query. Instead, use the ExecSQL

method of the TQuery component, as in:

   Query1.ExecSQL;

The reason for this is that, unlike with a normal query, an update

query does not display data. It acts on data. So remember it as queries

that display data can be opened (Open method) or activated (Active :=

True), and update queries must be executed (ExecSQL). For more on this,

see page 120 of the Database Application Developer's Guide, in the

paragraph just below Table 5.1. Also see the section "Executing a query"

on page 119 of the same manual.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


Delphi: help on Unit, TQuery, OOP database?

#1031.BDE	From: koterski@genghis (Steve Koterski)

Jin Mai (mwj@nyc.pipeline.com) wrote:

: I try to define a class which reads data from a paradox table.

: I want to put this class in a unit file(not a form file).

: It seems that delphi limits database access only to a form

: file by drag and drop the data access control to the form.

: Is there anyway to give database access to the class without

: define to class in a form unit?

Yes, you can. But do not mistake the automatic data accessing of the

data-aware components that are used on a Form for the ability to

programmatically access data. The two are distinct issues.

Delphi provides components that have inherent capabilities to access

the data from a data source. Examples of these components include the

TDBEdit, the TDBGrid, and the TDBMemo. These components are designed as

visual manifestations of the data, visible on a Form. These components

get these abilities by calls made to the Borland Database Engine (BDE).

But your access to data is not just limited to using these visual

components. You can make these calls to the BDE to access data totally

separate from any component or in a component of your own making. You

could, in other words, create a custom object that has no visual

manifestation and that makes its own calls to the BDE, storing retrieved

data values into its member properties.

Take a look at the help topic "Overview of Accessing the BDE." The functions

that comprise the BDE are not as well documented as they are in the docs

that come with the BDE. This would necessitate a close study of the

internal behavior of the data-aware components using the Visual Components

Library (VCL) source code to see how this is done.

Another option might be to create an object of one of the non-visual data

classes, such as a TTable or a TQuery and calling that object's inherent

methods to extract data.

: This lead to another question, does Delphi support object

: oriented database application? If it does, then why can't

: I define a low base class without assocate the class to a window

: (form)?

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


Delphi Heterogenous SQL Select

#1032.BDE	From: koterski@genghis (Steve Koterski)

D.M. (Mike) Mattix (dmmatt@ccmail.monsanto.com) wrote:

: I would like to do a Heterogenous SQL Select as shown in the manual.  I am

: attempting to access two different DEC/Oracle Rdb Databases via ODBC.  I set

: up the aliases in the BDE Configurator, I pull a Query into my form, I put

the

: SQL syntax in just as in the Manual (I think..), and presto "Undefined

: Variable' message as soon a I activate the Query.

: The syntax (generically) is:

:       Select A.Field1, B.Field2, A.Field3, A.Field4 from

:               :FIN:Table1 A, :RDS:Table2 B where

:               A.Field5 = B.Field5

: It seems to treat the Alias FIN as a variable (: insertion, etc).  The

: examples in the book (and the help) are not reallllll clear on this subject.

: I thought it might be due to the declaration of the FIN database as the

: database name in the Query object but if I remove this the activate says

that

: I have to have a Database..  I tried other syntax (various..) "FIN:Table1",

: ":FIN:Table1", and others.  I then get SQL Syntax errors from the Rdb ODBC

: driver.

The colon (":") is used as a designator for a dynamic parameter in SQL

statements. An example of this can be seen on page 122 of the Database

Application Developer's Guide, in the first code example on the page. In

that example, Name is a parameter, expressed as ":Name".

Try creating a simple SQL statement using the Database Desktop (DBD) to

see how it expects table name qualifiers to be expressed. Typically,

this is with dot notation, as in:

   FIN.Table

An SQL statement built in DBD can then be copied to the clipboard and then

pasted into the SQL property of a TQuery component on a Form, where you

can further modify it manually.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


dbase files on a LAN and DELPHI

#1033.BDE	From: koterski@genghis (Steve Koterski)

eric abrams (eabrams@red.weeg.uiowa.edu) wrote:

: Is there a way to make dbase files readable by everyone on a network yet

: modifiable by only one person within Delphi?

: The modify rights will change from person to person so I also want to know

if

: I can change these rights on an open dataset.

: Let me know.

Well, there is a ReadOnly property for the TTable component, and this

can be set at run-time (although it must be set when the TTable is not

active). You could set this based on some criteria (a password entered

on starting the app?) for some users but not for others.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


DELPHI: read/write 1 rec. not on screen!

#1034.BDE	From: Chuck Jazdzewski <cjaz@borland.com>

marwk@levels.unisa.edu.au wrote:

>

> Here is a simple request for DELPHI to perform - it is trivial in Object

Pal!

>

> Object Pal version:

>

> var

>   tc  TCursor

> endVar

>

>   tc.open("ANIMALS")

>   name.value = tc.Name   ; show the name of the first record on the screen

>   tc.edit()

>   tc.Age = tc.age + 1    ; increment the age of the animal

>   tc.close()

>

> How is this done in DELPHI??

>

> It should be obvivous, but it isn't.  It seems to require a whole heap of

> widgets on the screen.

>

Try this:

  var

    TC: TTable;

  begin

    TC := TTable.Create(Self);

    try

      TC.TableName := 'ANIMALS';

      TC.Open;

      TC.Edit;

      TC.FieldByName('Age').AsInteger := TC.FieldByName('Age').AsInteger + 1;

      TC.Post;

    finally

      TC.Free;

    end;

  end;

NOTE: The try..finally is necessary to ensure TC gets free'ed even

if there is an error opening the table.

It would be easier if you dropped a table object on the form named

TC and set the TableName property.  The code could look like:

  begin

    TC.Open;

    TC.Edit;

    TC.FieldByName('Age').AsInteger := TC.FieldByName('Age').AsInteger + 1;

    TC.Post;

  end;

If you go into the fields editor (by double-clicking the table)

and create fields on the table the code could look like:

  begin

    TC.Open;

    TC.Edit;

    TCAge.Value := TCAge.Value + 1;

    TC.Post;

  end;

Chuck Jazdzewski (cjaz@borland.com)

Delphi Development

From: Grant Carpenter

>   [Raymond Kennington] marwk@levels.unisa.edu.au writes:

>  Here is a simple request for DELPHI to perform - it is trivial in Object

Pal!

Agreed--Does anyone else miss the handy tc?

>  Object Pal version:

>

>  var

>    tc  TCursor

>  endVar

>

>    tc.open("ANIMALS")

>    name.value = tc.Name   ; show the name of the first record on the screen

>    tc.edit()

>    tc.Age = tc.age + 1    ; increment the age of the animal

>    tc.close()

>

>  How is this done in DELPHI??

>

>  It should be obvivous, but it isn't.  It seems to require a whole heap of

>  widgets on the screen.

It does seem to require a lot of components. I think you can do what you want

by...

- add a table control to your form

- set its database name to the proper alias

- set its table name to "ANIMALS.DB" (called something like TblAnimals)

- leave it inactive

- if you only want to work with the first record in the table ...

(to set a display control (ie an editbox) to Name.Value and increment

Age.Value)

TblAnimals.Active := True;

Edit1.Text := TblAnimals.Field[n].AsString;  {n is whatever field number,

  zero-based, you can also do this with the name...}

TblAnimals.Edit;

TblAnimals.Field[n].AsInteger := TblAnimals.Field[n].AsInteger + 1;

TblAnimals.Active := False;

I'm not sure this is precise, you might need to call a post on tblanimals,

but hopefully it'll get you started. If you combine it with a SetKey and

GotoNearest (check the helpfiles) you can seek out a specific record. The

table will open on the first row, otherwise.

I spent an evening trying to construct a moderate dynamic query and then

select records to add to another table--I ended up with about five data

access controls (two datasources, a query, a table, and a batch move) until I

realized I could lose a datasource and the batch move. The Table.InsertRecord

and Field objects will help replace some of that handy tc functionality.

Grant Carpenter

+++++++++++++++++++++++++++++++++++

grant@pinadvgrp.com

gcarpent@interserv.com

pinnacleMA@aol.com


What data-aware controls come w/ it?

#1035.BDE	From: Steve Teixeira <steixeir@borland.com>

gutierrm@manta.nosc.mil (Mario L Gutierrez) wrote:

>

> I'm interested in Delphi.  What data-aware controls come with the regular

> version (not client/server)?  Specifically, I would be interested in a

> good grid/spreadsheet control.

>

> --

> mario

>

Both versions contain the same data-aware components:

TDBGrid (a data grid)

TDBEdit (an edit control)

TDBNavigator (a navigator with buttons to move around in a table)

TDBLabel (a label control)

TDBMemo (a multiline edit control useful for text blobs)

TDBImage (a component that displays graphic fields)

TDBRadioButton and TDBCheckBox (self-explanitory)

TDBListBox, TDBComboBox, TDBLookupListBox, TDBLookupComboBox

        -Steve Teixeira

         steixeir@borland.com


Indexed Paradox Tables Database in Delphi

#1036.BDE	From: joser@news.dorsai.org ()

Alfonso Sanz US/PAT #45021 (sanz@sls812.NoSubdomain.NoDomain) wrote:

: Does Delphi allow to use indexed paradox-tables? Is it also possible to use

a complex

: paradox-database (several reletation and indexes)

: best regards

: A. Sanz

Most definitely!

--

Jose R. Nebro

joser@dorsai.org

       /////  ///////  //      //

        /    //   //  //\     //

       /    //////   // \    //

      /    // \     //   \  //

  ////    //   \   //     \//

From: Steve Teixeira <steixeir@borland.com>

Subject: Re: Database in Delphi

Date: 14 Mar 1995 19:03:28 GMT

sanz@sls812.NoSubdomain.NoDomain (Alfonso Sanz US/PAT #45021) wrote:

>

> Does Delphi allow to use indexed paradox-tables? Is it also possible to use

a complex

> paradox-database (several reletation and indexes)

>

> best regards

>

> A. Sanz

Yep and Yep.  Delphi uses the same database engine as Pdox/Win, so, generally

speaking, if it's possible in Pdox, it's possible in Delphi.

        -Steve Teixeira

         steixeir@borland.com


Delphi Database Examples

#1037.BDE	From: higgins@cs.niu.edu (Greg Higgins)

In article <3k08ta$mm8@mp.cs.niu.edu>,

Greg Higgins <higgins@happmis.com> wrote:

 | In item 9) It defines an event handler for the OnCalcFields

 | event.

 |

 | It references Parts.FindKey ;

 |

 | I created a table object for parts, i defined the previously

 | unmentioned ItemsDescription. I installed a DataSource for parts.

 |

 | Still, when I start my application I get an error on the line

 |

 |      If Parts.FindKey( [...

 |

 | Of course, I also installed parts.open in the form create handler.

This turned out to be the problem. In my code I had the following:

        procedure TOrderForm.FormCreate(Sender: TObject);

        begin

          Parts.Open;

          Items.Open;

        end;

For some reason, this doesn't work. Either the call to the

open method is merely a hint, or it's asynchonous and doesn't

require the table to actually be open or whatever....

Anyway, the following does work:

        procedure TOrderForm.FormCreate(Sender: TObject);         {Works}

        begin

          Items.Open;

        end;

        procedure TOrderForm.ItemsBeforeOpen(DataSet: TDataset);

        begin

          Parts.Open;

        end;

I also tried

        procedure TOrderForm.FormCreate(Sender: TObject); {Doesn't work}

        begin

          Parts.Open;

          Items.AutoCalcFields := False;

          Items.Open;

          Items.AutoCalcFields := True; {Also leaving it false}

        end;

but still got the closed dataset message.

-- greg

  higgins@happmis.com

From: Marc@landscap.demon.co.uk (Marc Palmer)

In article: <3k4cih$il2@mp.cs.niu.edu>  higgins@cs.niu.edu (Greg Higgins)

writes:

>

> In article <3k08ta$mm8@mp.cs.niu.edu>,

> Greg Higgins <higgins@happmis.com> wrote:

>  | In item 9) It defines an event handler for the OnCalcFields

>  | event.

>  |

>  | It references Parts.FindKey ;

>  |

>  | I created a table object for parts, i defined the previously

>  | unmentioned ItemsDescription. I installed a DataSource for parts.

>  |

>  | Still, when I start my application I get an error on the line

>  |

>  |    If Parts.FindKey( [...

>  |

>  | Of course, I also installed parts.open in the form create handler.

>

> This turned out to be the problem. In my code I had the following:

>

>       procedure TOrderForm.FormCreate(Sender: TObject);

>       begin

>         Parts.Open;

>         Items.Open;

>       end;

>

>

> For some reason, this doesn't work. Either the call to the

> open method is merely a hint, or it's asynchonous and doesn't

> require the table to actually be open or whatever....

I have no problem doing that. My application opens 3 tables just so, and at

design time their Active properties are set to False. I only use

Auto-calc'd fields on one of the tables though.

> Anyway, the following does work:

>

>         procedure TOrderForm.FormCreate(Sender: TObject);         {Works}

>         begin

>           Items.Open;

>         end;

>

>       procedure TOrderForm.ItemsBeforeOpen(DataSet: TDataset);

>       begin

>         Parts.Open;

>       end;

>

>

[snip]

********************************************************************

* Marc P.                               E-Mail me for PGP 2.6 key  *

********************************************************************


Stopping inserting in Delphi TDBGrids

#1038.BDE	From: koterski@genghis (Steve Koterski)

Business Transformations (BTQld@OntheNet.com.au) wrote:

: I've got a problem with my TDBGrids. They're so useful I tend to use

: them a lot. But in the present database application that I'm working

: on I want to make the user add the records one at a time so that

: valid values of his choice go into certain fields. Unfortunately,

: with TDBGrids, you can add records just by holding down the down

: arrow.

: Does anyone know how to stop that from happening? I'd appreciate not

: having to do a major re-write.

You might want to look at the BeforePost method of TTable. This allows

you to intercept an attempt to post a new record or a change to an

existing record, and optionally/conditionally abort that post before it

actually occurs. This will not prevent the appearance of adding a new

row through the TDBGrid, just the actual posting of the new record.

If you want to suppress the appearance of a new record in a TDBGrid

altogether, consider another approach the the problem. Consider making

the underlying TTable read-only (setting the ReadOnly property to

True) and effecting the adding of a new row in the table via a dialog

box. The dialog would use another TTable pointing to the same table,

or a TDataSource pointing to the TTable on the original Form but

temporarily changing the ReadOnly property to False.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

From: danm@wv.mentorg.com (Dan Milliron)

Business Transformations (BTQld@OntheNet.com.au) wrote:

: I've got a problem with my TDBGrids. They're so useful I tend to use

: them a lot. But in the present database application that I'm working

: on I want to make the user add the records one at a time so that

: valid values of his choice go into certain fields. Unfortunately,

: with TDBGrids, you can add records just by holding down the down

: arrow.

To inhibit *ALL* record insertion, put an "Abort;" command in the TDBGrid's

OnInsert handler.  This will raise a silent exception that keeps the insert

from happening.  Similarly, you can prevent record deletion by putting the

Abort command in the OnDelete handler.

If you want to allow insertion in some cases (for example, when the user

clicks an "insert" button), then you can make the Abort command conditional

on something, such as the state of the insert button.

There may be better ways, but I had this same problem and came up with this

solution.  I wish that TDBGrids had an AutoAppend property ala Paradox

table grids.

--Dan Milliron


Error 70: Unit Version Mismatch- why?

#1039.BDE	From: dmurdoch@mast.queensu.ca (Duncan Murdoch)

In article <3lqc9v$1ae@dns1.NMSU.Edu> smargari@NMSU.EDU (Susan Margarit)

writes:

>I cannot get past a 'Error 70: Unit Version Mismatch 'DBTables''

>error when I compile my project. Help tells me that DBTables (ie

>TTable) was compiled with a different version of Delphi. This seems

>a little unlikely. It had compiled successfully in the past. Is

>there a more plausible reason for this message? I have already

>reinstalled Delphi.

This is usually caused when you've got two copies of DBTables.DCU on your

disk, possibly because you've chosen that name for one of your own units.

Find the second one and delete it; then rename the unit and recompile.

Duncan Murdoch


Some Delphi Questions

#1040.BDE	From: Steve Teixeira <steixeir@borland.com>

james.obrien@yale.edu (James A. O'Brien) wrote:

>

> In article <3k23mg$8as@www.uno.edu> slp@uno.edu writes:

> > anybody know what

> >might be going on?

> >

> I don't.

>

> >2)...if there's a quick/straightforward/automated way of converting a

> >Resource Compiler script Dialog definition into a Delphi form.  Is there

> >such an animal?

> >

> Not yet.  One is rumored to be forthcoming from Borland.

>

> >3) In similar vein, does Delphi offer a straightforward way of creating

> >and accessing string table resources?

> >

> Nope.  You need RW or something equivalent.

>

StringTable resources actually aren't too difficult to do in text editor, and

Delphi does comes with a command-line resource compiler.

        -Steve Teixeira

         steixeir@borland.com

From: danm@wv.mentorg.com (Dan Milliron)

slp@uno.edu wrote:

: 2) I've searched the docs to some extent (not exhaustively I'll admit,

: so if the answer is RTFM, okay, gimme a hint where); but can find no

: mention if there's a quick/straightforward/automated way of converting a

: Resource Compiler script Dialog definition into a Delphi form.  Is there

: such an animal? I have discovered that a .DFM file is just (?) a .RES

: file containing a single RCDATA definition, presumably of the associated

: form, but that doesn't give me any clues on conversion.

If you to a File->Open File on a .DFM file, Delphi converts it from binary

to human-readable before displaying it.  When you save it back out, the

human-readable gets converted back to binary.

So one answer to your question would be to do Open File on the .DFM, cut

and paste the desired .RES file contents into the human-readable display,

then save the .DFM back out.

I have not tried this, and I hope there is a more straightforward way.

--Dan Milliron


BDE and other data base types

#1041.BDE	From: lfosdal@falcon.no (Lars Fosdal)

In <shane.11.2F68FA30@gandalf.otago.ac.nz> shane@gandalf.otago.ac.nz (Shane

Sturgeon) writes:

>I see a lot of news traffic regarding using Delphi to connect to external

>databases. I have very little knowledge of Delphi but would desperately like

>to know if Dephi has its own database object and if so, is it relational or

of

>a flat file type. Delphi sounds really good but if I have to have some

>external DB program to create the tables etc it is unfortunately not much use

>to me. I prefer my databases to be encompassed in a single file such as

Access

>rather than in Paradox's manner of multiple files so any information

regarding

>both the database functions and how its implemented in terms of files would

be

>much appreciated.

Delphi incorporates the Borland Database engine, and hence you can

create Paradox, dBase, and InterBase tables directly from your Delphi

application (i.e. programatically (sp?)).

Also, the Delphi database objects isolates you from the actual database,

so you might use any of the supported databases with very little change

to the code.  So, if your customer prefers dBase, you could set up your

app to use dBase, or if he already is running InterBase, MS SQL server,

Oracle, SyBase or Informix, your app could use those instead.

You can also use ODBC drivers to access any other database, but the ODBC

layer has a certain impact on performance which is dependant on the quality

of the respective ODBC database drivers.

The local InterBase engine stores multiple tables / indexes within a

single file similar to how Access does.  Another interresting point about

the local InterBase tables, is that they are binary compatible with the

Windows NT InterBase SQL server tables, so you can switch from using a

local InterBase table to using an central SQL server without any effort

or pain at all.  How's that for scalability?

Lars F.

--

/ Mr.Lars Fosdal    / Falcon AS   (a REUTERS company) / Tel.+47 22831310


Delphi DB Aware List Box

#1042.BDE	From: GREGORY MCBRIDE <mcbride@gaul.csd.uwo.ca>

gtynen@netcom.com (Gerard Tynen) wrote:

> I seem to be able to do this fine with the other data aware controls like

the grid, combo box,

> memos, and labels, but with the list box nothing shows up.  Is there

something different about

> the data aware listbox?

>

Try using a TDBLookupListBox. This will allow you to fill the list with a

column from your

lookup table ( specified in lookupsource parameter ) and give the selected

values to

your datasource.

greg.

From: olivas@deltanet.com (Sergio Olivas)

>I am trying to connect a Delphi TDBListBox to a column in an MS Access

database table.

>I seem to be able to do this fine with the other data aware controls like the

grid, combo box,

>memos, and labels, but with the list box nothing shows up.  Is there

something different about

>the data aware listbox?

>

Hmm... Perhaps you are fogetting to open the TTable for the Access

table in the OnCreate function?

Sergio Olivas

From: Marc@landscap.demon.co.uk (Marc Palmer)

In article: <3kk8um$hlh@alterdial.UU.NET>  olivas@deltanet.com (Sergio Olivas)

writes:

>

> >I am trying to connect a Delphi TDBListBox to a column in an MS Access

database table.

> >I seem to be able to do this fine with the other data aware controls like

the grid, combo box,

> >memos, and labels, but with the list box nothing shows up.  Is there

something different about

> >the data aware listbox?

As another thread said, you can use the TDBLookupList.

I've found another interesting way to do this. I want a list that shows

the name and address of the customers in my table. Now, the name and

address details are stored in separate fields (Name, A1, A2, A3, A4,

PostCode, Country). The problem I had was that I don't want the grid

to show these fields in different columns.

For example, DBGrid would give:

Marc Palmer        Address1           Address2         Address3

and so on, so the user would always have to scroll right to see the other

details. What I want in the list is this:

Marc Palmer, Address1, Address2, Address3, Address4, KF55 7GO, England

To do this you use the Fields Editor to create persistant

instances of all the fields you need from the table. Highlight them all

and set all of their visible properies to FALSE. Create another

(calculated) field called ListEntry (as a string in my case) and make

sure it's Visible property is TRUE. Now, in the table's OnCalcFields

event simply set the Table1ListEntry.Value property to what you want

(based on the other field's values) i.e.

procedure TTable1.OnCalcFields( {can't remember params } );

begin

  Table1ListEntry.Value := Table1Name.Value+', '+Table1Address1.Value+

{ and so on for all fields. Obviously you have to cover for blank fields}

end;

Hey presto the DBGrid only shows one 'column', but that column contains

all the data you want, formatted any way you want.

This is a very easy solution I think you'll agree.

Viva Calculated fields !

********************************************************************

* Marc P.                               E-Mail me for PGP 2.6 key  *

********************************************************************

From: Greg McBride <mcbride@gaul.csd.uwo.ca>

olivas@deltanet.com (Sergio Olivas) wrote:

>

> >I am trying to connect a Delphi TDBListBox to a column in an MS Access

database table.

> >I seem to be able to do this fine with the other data aware controls like

the grid, combo box,

> >memos, and labels, but with the list box nothing shows up.  Is there

something different about

> >the data aware listbox?

>

You likely need to use a TDBLookUpListBox which will use a lookup table as the

source

for its information and connect your selection at run time to a datasource.

The TDListBox is still designed to be filled with items in code, not from a

table.

Greg McBride


HOW TO CIRCUMVENT THE "INDEX NOT FOUND" EXCEPTION

#2001.BDE	From BORLAND

{

Q: How do I open a dBASE table without the required MDX file?

   I keep getting an "Index not found..." exception.

A: When you create a dBASE table with a production index (MDX), a

   special byte is set in the header of the DBF file.  When you

   subsequently attempt to re-open the table, the dBASE driver

   will read that special byte, and if it is set, it will also

   attempt to open the MDX file.  When the MDX file cannot be

   opened, an exception is raised.

   To work around this problem, you need to reset the byte (byte

   28 decimal) in the DBF file that causes the MDX dependency

   to zero.

   The following unit is a simple example of how to handle the

   exeption on the table open, reset the byte in the DBF file,

   and re-open the table.

}

unit Fixit;

interface

uses

  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics,

  Controls, Forms, Dialogs, StdCtrls, DB, DBTables, Grids, DBGrids;

type

  TForm1 = class(TForm)

    Table1: TTable;;

    Button1: TButton;

    procedure Button1Click(Sender: TObject);

  private

    { Private declarations }

  public

    { Public declarations }

  end;

var

  Form1: TForm1;

implementation

{$R *.DFM}

const

  TheTableDir = 'c:\temp\';

  TheTableName = 'animals.dbf';

procedure RemoveMDXByte(dbFile: String);

{ This procedure accepts a DBF file as a parameter.  It will patch}

{ the DBF header, so that it no longer requires the MDX file }

const

  Value: Byte = 0;

var

  F: File of byte;

begin

  AssignFile(F, dbFile);

  Reset(F);

  Seek(F, 28);

  Write(F, Value);

  CloseFile(F);

end;

procedure TForm1.Button1Click(Sender: TObject);

{ This procedure is called in response to a button click.  It    }

{ attempts to open a table, and, if it can't find the .MDX file, }

{ it patches the DBF file and re-execute the procedure to        }

{ re-open the table without the MDX  }

begin

  try

    { set the directory for the table }

    Table1.DatabaseName := ThheTableDir;

    { set the table name }

    Table1.TableName := TheTableName;

    { attempt to open the table }

    Table1.Open;

  except

    on E:EDBEngineError do

      { The following message indicates the MDX wasn't found: }

      if Pos('Index does not exist. File', E.Message)>0 then begin

        { Tell user what's going on. }

        MessageDlg('MDX file not found.  Attempting to open

                    without index.', mtWarning, [mbOk], 0);

        { remove the MDX byte from the table header }

        RemoveMDXByte(TheTableDir + TheTableName);

        { Send the button a message to make it think it was }

        { pressed again.  Doing so will cause this procedure to }

        { execute again, and the table will be opened without }

        { the MDX }

        PostMessage(Button1.Handle, cn_Command, bn_Clicked, 0);

      end;

  end;

end;

end.


CREATING DATABASE ALIASES IN CODE

#2003.BDE	From BORLAND

Typically, you use the BDE Configuration Utility BDECFG.EXE to

create and configure aliases outside of Delphi.  However, with

the use of the TDatabase component, you have the ability to

create and use this ALIAS within your application-- not

pre-defined in the IDAPI.CFG.

The ability to create Aliases that are only available within

your application is important.  Aliases specify the location

of database tables and connection parameters for database servers.

Ultimately, you can gain the advantages of using ALIASES within

your applications-- without having to worry about the existance

of a configuration entry in the IDAPI.CFG when you deploy your

application.

Summary of Examples:

------- -- ---------

Example #1:

Example #1 creates and configures an Alias to use

STANDARD (.DB, .DBF) databases.  The Alias is

    	then used by a TTable component.

Example #2:

Example #2 creates and configures an Alias to use

 	an INTERBASE database (.gdb).  The Alias is then

used by a TQuery component to join two tables of

the database.

Example #3:

Example #3 creates and configures an Alias to use

        STANDARD (.DB, .DBF) databases.  This example

demonstrates how user input can be used to

configure the Alias during run-time.

Example #1:  Use of a .DB or .DBF database (STANDARD)

1.  Create a New Project.

2.  Place the following components on the form:

     - TDatabase, TTable, TDataSource, TDBGrid, and TButton

3.  Double-click on the TDatabase component or choose Database

    Editor from the TDatabase SpeedMenu to launch the Database

    Property editor.

4.  Set the Database Name to 'MyNewAlias'.  This name will

    serve as your ALIAS name used in the DatabaseName Property for

    dataset components such as TTable, TQuery, TStoredProc.

5.  Select STANDARD as the Driveer Name.

6.  Click on the Defaults Button.  This will automatically add

    a PATH= in the Parameter Overrides section.

7.  Set the PATH= to C:\DELPHI\DEMOS\DATA

    (PATH=C:\DELPHI\DEMOS\DATA)

8.  Click the OK button to close the Database Dialog.

9.  Set the TTable DatabaseName Property to 'MyNewAlias'.

10.  Set the TDataSource's DataSet Property to 'Table1'.

11.  Set the DBGrid's DataSource Property to 'DataSource1'.

12.  Place the following code inside of the TButton's

     OnClick event.

procedure TForm1.Button1Click(Sender: TObject);

begin

          Table1.Tablename:= 'CUSTOMER';

          Table1.Active:= True;

end;

13.  Run the application.

***  If you want an alternative way to steps 3 - 11, place the

      following code inside of the TButton's OnClick event.

procedure TForm1.Button1Click(Sender: TObject);

begin

          Database1.DatabaseName:= 'MyNewAlias';

          Database1.DriverName:= 'STANDARD';

  Database1.Params.Clear;

          Database1.Params.Add('PATH=C:\DELPHI\DEMOS\DATA');

          Table1.DatabaseName:= 'MyNewAlias';

          Table1.TableName:= 'CUSTOMER';

          Table1.Active:= True;

          DataSource1.DataSet:= Table1;

          DBGrid1.DataSource:= DataSource1;

end;

*****

Example #2: Use of a INTERBASE database

1.  Create a New Project.

2.  Place the following components on the form:

     - TDatabase, TQuery, TDataSource, TDBGrid, and TButton

3.  Double-click on the TDatabase component or choose Database

    Editor from the TDatabase SpeedMenu to launch the Database

    Property editor.

4.  Set the Database Name to 'MyNewAlias'.  This name will

    serve as your ALIAS name used in the DatabaseName Property for

    dataset components such as TTable, TQuery, TStoredProc.

5.  Select INTRBASE as the Driver Name.

6.  Click on the Defaults Button.  This will automatically add

    the following entries in the Parameter Overrides section.

SERVER NAME=IB_SERVEER:/PATH/DATABASE.GDB

USER NAME=MYNAME

OPEN MODE=READ/WRITE

SCHEMA CACHE SIZE=8

LANGDRIVER=

SQLQRYMODE=

SQLPASSTHRU MODE=NOT SHARED

SCHEMA CACHE TIME=-1

PASSWORD=

7.  Set the following parameters

SERVER NAME=C:\IBLOCAL\EXAMPLES\EMPLOYEE.GDB

USER NAME=SYSDBA

OPEN MODE=READ/WRITE

SCHEMA CACHE SIZE=8

LANGDRIVER=

SQLQRYMODE=

SQLPASSTHRU MODE=NOT SHARED

SCHEMA CACHE TIME=-1

PASSWORD=masterkey

8.  Set the TDatabase LoginPrompt Property to 'False'.  If you

    supply the PASSWORD in the Parameter Overrides section and set

    the LoginPrompt to 'False', you will not be prompted for the

    password when connecting to the database.  WARNING:  If an

    incorrect password in entered in the Parameter Overrides

    section and LoginPrompt is set to 'False', you are not prompted

    by the Password dialog to re-enter a valid password.

9.  Click the OK button to close the Database Dialog.

10.  Set the TQuery DatabaseName Property to 'MyNewAliias'.

11.  Set the TDataSource's DataSet Property to 'Query1'.

12.  Set the DBGrid's DataSource Property to 'DataSource1'.

13.  Place the following code inside of the TButton's

     OnClick event.

procedure TForm1.Button1Click(Sender: TObject);

begin

          Query1.SQL.Clear;

          Query1.SQL.ADD(

'SELECT DISTINCT * FROM CUSTOMER C, SALES S

WHERE (S.CUST_NO = C.CUST_NO)

ORDER BY C.CUST_NO, C.CUSTOMER');

          Query1.Active:= True;

end;

14.  Run the application.

Example #3: User-defined Alias Configuration

This example brings up a input dialog and prompts the

user to enter the directory to which the ALIAS is to

be configured to.

The directory, servername, path, database name, and other

neccessary Alias parameters can be read into the

application from use of an input dialog or .INI file.

1.  Follow the steps (1-11) in Example #1.

2.  Place the following code inside of the TButton's

    OnClick event.

procedure TForm1.Buttton1Click(Sender: TObject);

var

  NewString: string;

  ClickedOK: Boolean;

begin

  NewString := 'C:\';

  ClickedOK := InputQuery('Database Path',

'Path: --> C:\DELPHI\DEMOS\DATA', NewString);

  if ClickedOK then

  begin

    Database1.DatabaseName:= 'MyNewAlias';

    Database1.DriverName:= 'STANDARD';

    Database1.Params.Clear;

    Database1.Params.Add('Path=' + NewString);

     Table1.DatabaseName:= 'MyNewAlias';

    Table1.TableName:= 'CUSTOMER';

    Table1.Active:= True;

    DataSource1.DataSet:= Table1;

    DBGrid1.DataSource:= DataSource1;

  end;

end;

3.  Run the Application.


CREATING & DELETING TFIELDS AT RUN-TIME

#2004.BDE	From BORLAND

TField components (or more appropriately, descendants of the TField

component of types corresponding to field types) can be created at design-

time using the Fields Editor. The Fields Editor is invoked by double-

clicking on the design icon for a TTable or TQuery component. But TField

descendants can also be created and deleted at run-time.

Descendants of the TField component (such as TStringField, TIntegerField,

etc.) are created by invoking the Create method for the type of TField

descendant appropriate to the field in the data set. That is, the Create

method for the TStringField descendant of TField would be called to create

a TField descendant for a string-type field in the current data set. The

Create method requires one parameter, that of the owner of the TField

descendant, which is the containing TForm. After creating the TField

descendant component, a number of key properties need to be set in order

to connect it with the field in the data set. These are:

FieldName: the name of the field in the table.

Name:      a unique identifier for the TField descendant component.

Index:     the TField descendant component's position in the array of

           TFields (the Fields property of the TTable or TQuery with which

           the TField will be associated).

DataSet:   the TTable or TQuery with which the TField will be associated.

The code snippet below demonstrates creating a TStringField. The

containing TForm is called Form1 (referred to here with the Self

variable), the active data set is a TQuery named Query1, and the field for

which the TStringField component is being created is a dBASE table field

named CO_NAME. This new TField descendant will be the second TField in the

Fields array property of Query1. Note that the data set with which the new

TField descendant will be associated (in this case, Query1) must be closed

prior to adding the TField and then reopened afterwards.

procedure TForm1.Button2Click(Sender: TOObject);

var

  T: TStringField;

begin

  Query1.Close;

  T := TStringField.Create(Self);

  T.FieldName := 'CO_NAME';

  T.Name := Query1.Name + T.FieldName;

  T.Index := Query1.FieldCount;

  T.DataSet := Query1;

  Query1.FieldDefs.UpDate;

  Query1.Open;

end;

The example above example creates a new TStringField named Query1CO_NAME.

Deleting an existing TField descendant is merely a matter of invoking the

Free method for that component. In the example below, the TForm's Find-

Component method is used to return a pointer to the TStringField component

named Query1CO_NAME. The return value for the FindComponent will either be

of type TComponent if successful or nil if unsuccessful. This return value

can be used to determine whether the component actually exists prior to

invoking its Free method.

procedure TForm1.Button1Click(Sender: TObject);

var

  TC: TComponent;

begin

  TC := FindComponent('Query1CO_NAME');

  if not (TC = nil) then begin

    Query1.Close;

    TC.Free;

    Query1.Open;

  end;

end;

As with creating a TField, if the data set associated with the TField

descendant is currently active, it must be closed or deactivated prior to

invoking this method.


ITERATING THROUGH THE FIELDS OF A TABLE

#2005.BDE	From BORLAND

There are a number of reasons why a program might need to query the

structure of a table used in the application. One reason is a prelude to

creating TField components at run-time that represent the fields in the

table. The information gleaned from the structure of the table form the

basis of the TField components to be created.

The example below demonstrates how to iterate through the fields available

in a TTable or TQuery. The example extracts information about the available

fields and displays the information in a TListBox, but the same methodology

can be used to provide information necessary for the dynamic building of

TField descendants. The example uses a TTable as the data set, but a TQuery

can be used in the same manner as both TTable and TQuery components incorp-

orate the Field-Defs property the same way.

procedure TForm1.Button1Click(Sender: TObject);

var

  i: Integer;

  F: TFieldDef;

  D: String;

begin

  Table1.Active := True;

  ListBox1.Items.Clear;

  with Table1 do begin

    for i := 0 to FieldDefs.Count - 1 do begin

      F := FieldDefs.Items[i];

      case F.DataType of

        ftUnknown: D := 'Unknown';

        ftString: D := 'String';

        ftSmallint: D := 'SmallInt';

        ftInteger: D := 'Integer';

        ftWord: D := 'Word';

        ftBoolean: D := 'Boolean';

        ftFloat: D := 'Float';

        ftCurrency: D := 'Currency';

        ftBCD: D := 'BCD';

        ftDate: D := 'Date';

        ftTime: D := 'Time';

        ftDateTime: D := 'DateTime';

        ftBytes: D := 'Bytes';

        ftVarBytes: D := '';

        ftBlob: D := 'BLOB';

        ftMemo: D := 'Memo';

        ftGraphic: D := 'Graphic';

      else

        D := '';

      end;

      ListBox1.Items.Add(F.Name + ', ' + D);

    end;

  end;

  Table1.Active := False;

end;


GETTING A QUERY'S MEMO FIELD AS A STRING

#2010.BDE	From BORLAND

Place a query object on your form (Query1)

Place a Edit object on your form (Edit1)

Place a Button object on your form (Button1)

Double-Click on the query and add the memo field.

 (Biolife.db using notes field)

Set Query1's SQL property to: Select * from Biolife

Set Query1's Active property to: True

Add the following code to Button1's OnClick event:

procedure TForm1.Button1Click(Sender: TObject);

var

  bs : TBlobStream;

  p  : array [0..50] of char;

begin

  FillChar(p, SizeOf(p), #0);

  bs:= TBlobStream.Create(Query1Notes, bmRead);

  try

    bs.Read(p,50);

  finally

    bs.Free;

  end;

  Edit1.Text:=StrPas(p);

end;


LOADING BITMAPS INTO DBASE/PARADOX BLOB FIELDS

#2014.BDE	From BORLAND

There are a number of ways to load a bitmap image into the BLOB field of a

dBASE or Paradox table. Three of the easier methods involve 1) copying the

data from the Windows clipboard into a TDBImage component connected to the

BLOB field, 2) using the LoadFromFile method of the TBLOBField component,

and 3) using the Assign method to copy an object of type TBitmap into the

Picture property of a TBDBImage.

The first method, copying the bitmap from the clipboard, is probably most

handy when an application needs to add bitmaps to a table when the end-

user is running the application. A TDBImage component is used to act as an

interface between the BLOB field in the table and the image stored in the

clipboard. The PasteFromClipboard method of the TDBImage component is

invoked to copy the bitmap data from the clipboard into the TDBImage. When

the record is posted, the image is stored into the BLOB field in the

table.

Because the Windows clipboard can contain data in formats othher than just

bitmap, it is advisable to check the format prior to calling the CopyFrom-

Clipboard method. To do this, a TClipboard object is created and its Has-

Format method is used to determine if the data in the clipboard is indeed

of bitmap format. Note that to use a TClipboard object, the Clipbrd unit

must be included in the Uses section of the unit that will be creating

the object.

Here is an example showing the contents of the clipboard being copied into

a TDBImage component, if the contents of the clipboard are of bitmap

format:

  procedure TForm1.Button1Click(Sender: TObject);

  var

    C: TClipboard;

  begin

    C := TClipboard.Create;

    try

      if Clipboard.HasFormat(CF_BITMAP) then

        DBImage1.PasteFromClipboard

      else

        ShowMessage('Clipboard does not contain a bitmap!');

    finally

      C.Free;

    end;

  end;

The second method of filling a BLOB field with a bitmap involves loading

the bitmap directly from a file on dissk into the BLOB field. This method

lends itself equally well to uses at run-time for the end-user as for

the developer building an application's data.

This method uses the LoadFromFile method of the TBLOBField component, the

Delphi representation of a dBASE for Windows Binary field or a Paradox for

Windows Graphic field, either of which may be used to store bitmap data

in a table.

The LoadFromFile method of the TBLOBField component requires a single

parameter: the name of the bitmap file to load, which is of type String.

The value for this parameter may come from a number of sources from the

end-user manually keying in a valid file name to the program providing a

string to the contents of the FileName property of the TOpenDialog comp-

onent.

Here is an example showing the use of the LoadFromFile method for a

TBLOBField component named Table1Bitmap (a field called Bitmap in the

table associated with a TTable component named Table1):

  procedure TForm1.Button2Clicck(Sender: TObject);

  begin

    Table1Bitmap.LoadFromFile(

      'c:\delphi\images\splash\16color\construc.bmp');

  end;

The third method uses the Assign method to copy the contents of an object

of type TBitmap into the Picture property of a TDBImage component. An

object of type TBitmap might be the Bitmap property of the Picture object

property of a TImage component or it may be a stand-alone TBitmap object.

As with the method copying the data from the clipboard into a TDBImage

component, the bitmap data in the TDBImage component is saved into the

BLOB field in the table when the record is successfully posted.

Here is an example using the Assign method. In this case, a stand-alone

TBitmap object is used. To put a bitmap image into the TBitmap, the

LoadFromFile method of the TBitmap component is called.

  procedure TForm1.Button3Click(Sender: TObject);

  var

    B: TBitmap;

  begin

    B := TBitmap.Create;

    try

      B.LoadFromFile('c:\delphi\images\splashh\16color\athena.bmp');

      DBImage1.Picture.Assign(B);

    finally

      B.Free;

    end;

  end;


BDE - EXTRACTING A BITMAP FROM A BLOB FIELD
EXTRACTING A BITMAP FROM A BLOB FIELD

#2016.BDE	From BORLAND

Extracting a bitmap from a dBASE or Paradox blob field -- without first

saving the bitmap out to a file -- is a simple process of using the Assign

method to store the contents of the BLOB field to an object of type

TBitmap. A stand-alone TBitmap object or the Bitmap property of the

Picture object property of a TIMage component are examples of compatible

destinations for this operation.

Here is an example demonstrating using the Assign method to copy a bitmap

from a BLOB field into a TImage component.

  procedure TForm1.Button1Click(Sender: TObject);

  begin

    Image1.Picture.Bitmap.Assign(Table1Bitmap);

  end;

In this example, the TBLOBField object Table1Bitmap is a BLOB field in a

dBASE table. This TBLOBField object was created using the Fields Editor.

If the Fields Editor is not used to create TFields for the fields in the

table, the fields must be referenced using either the FieldByName method

or the Fields property, both part of the TTable and TQuery componentts. In

cases where one of those means is used to reference the BLOB field in a

table, the field reference must be type-cast as a TBLOBField object prior

to using the Assign method. For example:

  procedure TForm1.Button1Click(Sender: TObject);

  begin

    Image1.Picture.Bitmap.Assign(TBLOBField(Table1.Fields[1]));

  end;

A bitmap stored in a BLOB field may also be copied directly to a stand-

alone TBitmap object. Here is an example showing the creation of a

TBitmap object and storing into it a bitmap from a BLOB field.

  procedure TForm1.Button2Click(Sender: TObject);

  var

    B: TBitmap;

  begin

    B := TBitmap.Create;

    try

      B.Assign(Table1Bitmap);

      Image1.Picture.Bitmap.Assign(B);

    finally

      B.Free;

    end;

  end;


SEARCHING THROUGH QUERY RESULT SETS

#2021.BDE	From BORLAND

The TQuery component does not offer the index-based search capabilities of

the TTable component (FindKey, GotoKey, and GotoNearest). So how do you

search within the result data set from a TQuery to find a row with a spec-

ific field value?

One way to search a query result set is a sequential search. This type of

search starts at the first row in the data set and, in a While loop,

sequentially compares the value of a field in the row with a search value.

One of two results are possible: a value will be found (success) or the

end of the data set will be reached (failure). The problem with this way

of searching the data set is that the further into the data set a row with

a matching value is, the longer it takes to arrive at that row. And, a

failed search takes longest of all because it must go all the way to the

last row in the data set. If the data set being searched is a large one,

this process may take a considerable amount of time.

Here is a function that will perfoorm a sequential search of the result set

from a TQuery:

  function SeqSearch(AQuery: TQuery; AField, AValue: String): Boolean;

  begin

    with AQuery do begin

      First;

      while (not Eof) and (not (FieldByName(AField).AsString = AValue)) do

        Next;

      SeqSearch := not Eof;

    end;

  end;

This function takes three parameters:

  1. AQuery: type TQuery; the TQuery component in which the search is to

             be executed.

  2. AField: type String; the name of the field against which the search

             value will be compared.

  3. AValue: type String; the value being searched for. If the field is of

             a data type other than String, this search value should be

             changed to the same data type.

The Boolean return value of this function indicates the success (True) or

failure (False) of the search.

An alternative is using a bracketing approach. On a conceptual level, this

method acts somewhat like a bb-tree index. It is based on the given that

for a row at a given point in the data set, the value of the field being

searched compared to the search value will produce one of three possible

conditions:

  1. The field value will be greater than the search value, or...

  2. The field value will be less than the search value, or...

  3. The field value will be equal to the search value.

A bracketing search process uses this means of looking at the current row

in respect to the search value and uses it to successively reduce the rows

to be search by half, until only one row remains. This search field value

for this sole remaining row will either be a match to the search value

(success) or it will not (failure, and no match exists in the data set).

Functionally, this process lumps the condition of the search field being

less than or equal to the search value into a single condition. This

leaves only two possible results for the comparison of the current

search field valuue with the search value: less than/equal to or greater

than. Initially, a range of numbers is established. The low end of the

range is represented by an Integer, at the start of the search process set

to 0 or one less than the first row in the data set. The far end of the

range is also an Integer, with the value of the RecordCount property of

the TQuery. The current row pointer is then moved to a point half way

between the low and high ends of the range. The search field value at that

row is then compared to the search value. If the field value is less than

or equal to the search value, the row being sought must be in the lower

half of the range of rows so the high end of the range is reduced to the

current row position. If the field value is greater than the search value,

the sought value must be in the higher half of the range and so the low

end is raised to the current point. By repeating this process, the number

of rows that are encompassed in the range are successivelly reduced by

half. Eventually, only one row will remain.

Putting this into a modular, transportable function, the code would look

like that below:

  function Locate(AQuery: TQuery; AField, AValue: String): Boolean;

  var

    Hi, Lo: Integer;

  begin

    with AQuery do begin

      First;

      {Set high end of range of rows}

      Hi := RecordCount;

      {Set low end of range of rows}

      Lo := 0;

      {Move to point half way between high and low ends of range}

      MoveBy(RecordCount div 2);

      while (Hi - Lo) > 1 do begin

        {Search field greater than search value, value in first half}

        if (FieldByName(AField).AsString > AValue) then begin

          {Lower high end of range by half of total range}

          Hi := Hi - ((Hi - Lo) div 2);

          MoveBy(((Hi - Lo) div 2) * -1);

        end

        {Search field less than search value, value in far half}

        else begin

          {Raise low end of range by half of total range}

           Lo := Lo + ((Hi - Lo) div 2);

          MoveBy((Hi - Lo) div 2);

        end;

      end;

      {Fudge for odd numbered rows}

      if (FieldByName(AField).AsString > AValue) then Prior;

      Locate := (FieldByName(AField).AsString = AValue)

    end;

  end;

Because there will never be a difference of less than one between the low

and high ends of the range of rows, a final fudge was added to allow the

search to find the search value in odd numbered rows.

This function takes the same three three parameters as the SeqSearch

function described earlier.

The return value of this function is of type Boolean, and reflects the

success or failure of the search. As the search does move the row pointer,

the effects of this movement on the implicit posting of changed data and

on where the desired position of the row pointer should be after a failed

search should be taken into account in the calling application. For

instance, a TBookmark pointer might be used to return  the row pointer to

where it was prior to a search if that search fails.

How is this process better than a sequential search? First, in bracketing

the search value, only a fraction of the number of rows will be visited as

would be the case in a sequential search. Unless the row with the value

being sought is in the first 1,000 rows, this search method will be faster

than a sequential search. Because this process always uses the same number

of records, the search time will be consistent whether searching for the

value in row 1,000 or row 90,000. This is in contrast with the sequential

search that takes longer the farther into the data set the desired row is.

Can this method be used with any TQuery result set? No. Because of the way

this method works in basing the direction of the search as either high or

low, it depends on the row being ordered in a descending manner based on

the field in which the search will be conducted. This means that it can

only be used if the datta set is naturally in a sequential order or an

ORDER BY clause is used in the SQL statement for the TQuery. The size of

the result set will also be a factor when deciding whether to perform a

sequential or bracketing search. This process is most advantageous for

speed when used with larger result sets. With smaller sets (1,00 or less

rows), though, a sequential search will often be as fast or faster.


EXTRACTING INDEX DATA FROM A TABLE

#2022.BDE	From BORLAND

Getting a list of the indexes associated with a table at run-time can be

as simple as a call to the GetIndexNames method of the TTable, TQuery, or

TStoredProc component. The GetIndexNames method returns a list of the

that are available for the data set in the form of a TStrings list, which

may then be inserted into such visual components as a TListBox through its

Items property:

  ListBox1.Clear;

  Table1.GetIndexNames(ListBox1.Items);

Of course, the TStrings list returned by the GetIndexNames method need not

be used with a visual component. It could just as well serve as an array

of index names stored entirely in memory, that can be used as a list or

array.

But it is also possible to retrieve much more information about the

indexes for a table than just the names. Other descriptive attributes

include the name of each index, the names of the fields that comprise each

index, and the index options used when each index was created. Retrieving

these values is slighhtly more involved than the use of the GetIndexNames.

Basically, this process involves iterating through the IndexDefs property

of the TTable, TQuery, or TStoredProc component. The IndexDefs property is

essentially an array of records, one record for each index for the table.

Each index record contains information about the index. It is a relatively

straightforward process to iterate through this array of index descrip-

tions, extracting information about individual indexes.

The IndexDefs property of the TTable component contains information about

the indexes for the table used by the TTable, TQuery, or TStoredProc comp-

onent in use. The IndexDefs property itself has various properties that

allow for the extraction of information about specific indexes. The two

properties in the IndexDefs object are:

  Count: type Integer; available only at run-time and read-only; indicates

         the number ofentries in the Items property (i.e., the number of

         indexes in thhe table).

  Items: type TIndexDef; available only at run-time and read-only; an

         array of TIndexDef objects, one for each index in the table.

The Count property of the IndexDefs object is used as the basis for a

loop program construct to iterate through the Items property entries to

extract specific information about each index. Each IndexDef object con-

tained in the Items property consists of a number of properties that pro-

vide various bits of information that describe each index. All of the

properties of the IndexDef object are available only at run-time and are

all read-only. These properties are:

  Expression: type String; indicates the expression used for dBASE multi-

              field indexes.

  Fields:     type String; indicates the field or fields upon which the

              index is based.

  Name:       type String; name of the index.

  Options:    type TIndexOptions; characteristics of the index (ixPrimary,

              ixUnique, ettc.).

Before any index information (Count or Items) can be accessed, the Update

method of the IndexDefs object must be called. This refreshes or init-

ializes the IndexDef object's view of the set of indexes.

Examples

========

Here is a simple For loop based on the Count property of the IndexDefs

object that extracts the name of each index (if any exist) for the table

represented by the TTable component Table1:

  procedure TForm1.ListBtnClick(Sender: TObject);

  var

    i: Integer;

  begin

    ListBox1.Items.Clear;

    with Table1 do begin

      if IndexDefs.Count > 0 then begin

        for i := 0 to IndexDefs.Count - 1 do

          ListBox1.Items.Add(IndexDefs.Items[i].Name)

      end;

    end;

  end;

Below is an example showing how to extract information about indexes at

run-time, plugging the extracted values into a TStringGrid (named SG1).

  procedure TForm1.FormShow(Sender: TObject);

  var

    i: Integer;

    S: String;

  begin

    with Tablee1 do begin

      Open;

      {Refresh IndexDefs object}

      IndexDefs.Update;

      if IndexDefs.Count > 0 then begin

        {Set up columns and rows in grid to match IndexDefs items}

        SG1.ColCount := 4;

        SG1.RowCount := IndexDefs.Count + 1;

        {Set grid column labels to TIndexDef property names}

        SG1.Cells[0, 0] := 'Name';

        SG1.ColWidths[0] := 200;

        SG1.Cells[1, 0] := 'Fields';

        SG1.ColWidths[1] := 200;

        SG1.Cells[2, 0] := 'Expression';

        SG1.ColWidths[2] := 200;

        SG1.Cells[3, 0] := 'Options';

        SG1.ColWidths[3] := 300;

        {Loop through IndexDefs.Items}

        for i := 0 to IndexDefs.Count - 1 do begin

          {Fill grid cells for current row}

          SG1.Cells[0, i + 1] := IndexDefs.Items[i].Name;

          SG1.Cells[1, i + 1] := IndexDefs.Items[i].Fields;

          SG1.Cells[2, i + 1] := IndexDefs.Items[i].Expression;

          if ixPrimary in IndexDefs.Items[i].Options then

            S := 'ixPrimary, ';

          if ixUnique in IndexDefs.Items[i].Options then

            S := S + 'ixUnique, ';

          if ixDescending in IndexDefs.Items[i].Options then

            S := S + 'ixDescending, ';

          if ixCaseInsensitive in IndexDefs.Items[i].Options then

            S := S + 'ixCaseInsensitive, ';

          if ixExpression in IndexDefs.Items[i].Options then

            S := S + 'ixExpression, ';

          if S > ' ' then begin

            {Get rid of trailing ", "}

            System.Delete(S, Length(S) - 1, 2);

            SG1.Cells[3, i + 1] := S;

          end;

        end;

      end;

    end;

  end;

Special Considerations

======================

There are idiosyncracies associated with extracting information about

indexes for different table types that Delphi can access.

dBASE Tables

------------

With dBASE indexes, which properties of Fields and Expression will be

filled will depend on the type of index, simple (ssingle-field) or

complex (based on multiple fields or a dBASE expression). If the index

is a simple one, the Fields property will contain the name of the field

in the table on which the index is based and the Expression property will

be blank. If the index is a complex one, the Expression property will

show the expression on which the index is based (e.g., "Field1+Field2")

and the Fields property will be blank.

Paradox Tables

--------------

With Paradox primary indexes, the Name property will be blank, the Fields

property will contain the field(s) on which the index is based, and the

Options property will contain ixPrimary. With secondary indexes, the Name

property will contain the name of the secondary index, the Fields prop-

erty will contain the field(s) on which the index is based, and the

Options property may or may not have values.

The Fields property for indexes based on more than one field will show

the field names separated by semi-colons. Indexes based onn only a single

field will show the name of only that one field in the Fields property.

InterBase Tables

----------------

For both index types, single- or multiple-field, the Expression property

will be blank. For single-field indexes, the Fields property will contain

the field on which the index is based. For multi-field indexes, the Fields

property will show all of the multiple fields that comprise the index,

each separated by a semi-colon.

Indexes designated as PRIMARY when the CREATE TABLE command is issued will

have "RDB$PRIMARYn" in the Name property, where n is a number character

uniquely identifying the primary index within the database metadata.

Secondary indexes will show the actual name of the index.

Foreign key constraints also result in an index being created by the sys-

tem. These indexes appear in the IndexDefs property, and will have the

name "RDB$FOREIGNn" where n is a number character that uniquely identifies

the index within the database metaddata.

The Fields property for indexes based on more than one field will show

the field names separated by semi-colons. Indexes based on only a single

field will show the name of only that one field in the Fields property.


REDISTRIBUTING THE BORLAND DATABASE ENGINE (BDE)

#2023.BDE	From BORLAND

Follow the following steps in order to deploy the redistributable

BDE engine on a target machine:

1)  Format two diskettes in the diskette drive of the target

    machine.  Label the diskettes "Disk 1" and "Disk 2".

2)  From the DELPHI CD,  Copy the \REDIST\BDEINST\DISK1 directory

    to the diskette labeled "Disk 1" and

    \REDIST\BDEINST\DISK2 to the diskette "Disk 2".

3)  Insert the diskette labeled "BDE Install 1" to a floppy

    drive (We'll use drive A: in this example) of the target

    machine.

4)  Make sure there are no other programs running in Windows.

    From the Windows Program Manager select File|Run, enter

    "A:\DISK1\SETUP" in the space labeled "Command Line" and

    press "OK" to begin install of the Borland Database Engine

    on the target machine.

5)  A dialog labeled "Database Engine Install" will appear

    briefly, then a dialog labeled "preparing to install...",

    and finally a background screen labeled "BDE

    Redisttributable" will appear along with a dialog allowing

    you to Continue or Exit.  Press "Continue".

6)  A dialog "Borland Database Engine Location Settings" will

    appear and allow you to change the path for BDE programs

    and configuration file.  Leave the default settings at and

    press "Continue".

7)  The "Borland Database Engine Installation" dialog will

    appear and allow you to display previous dialogs, or

    execute the install.  Press "Install".

8)  Installation progress will display while files from the

    "Disk 1" diskette are processed.

9)  The "BDE Redistributable Install Request" dialog will appear.

    Load the diskette labeled "Disk 2".  Press "continue".

10) On completion, the "Borland Database Engine Installation

    Notification" dialog will inform you that BDE is installed.

    Press "Exit".

11) Exit Windows, remove any floppy disks from your drives and

    reboot the target machine.

    If default settings were used, changes listed below will have

    taken place.

    Two new directories, \IDAPI, and \IDAPI\LANGDRV will exist on

    the target machine.  Note that the BDE Configuration Utility,

    BDECFG.EXE is located in the \IDAPI directory. Language

    drivers will now be located in \IDAPI\LANGDRV as *.LD files.

    AUTOEXEC.BAT, CONFIG.SYS, AND SYSTEM.INI will not be affected.

WIN.INI in the \WINDOWS\SYSTEM directory will have new entries:

[IDAPI]

DLLPATH=C:\IDAPI

CONFIGFILE01=C:\IDAPI\IDAPI.CFG

[Borland Language Drivers]

LDPath=C:\IDAPI\LANGDRV


CASCADING DELETES WITH PARADOX REFERENTIAL INTEGRITY

#2024.BDE	From BORLAND

Paradox tables offer a Referential Integrity feature. This feature pre-

vents adding records to a child table for which there is no matching

record in the parent table. It will also cause the key field(s) in the

child table to be changed when the corresponding key field(s) in the

parent are changed (commonly referred to as a cascading update). These

events occur automatically, requiring no intervention by a Delphi appli-

cation using these tables. However, the Paradox Referential Integrity

feature will not accommodate cascading deletes. That is, Delphi will not

allow you to delete a record in the parent table while matching records

exist in the child table. This would make "orphans" of the child records,

losing referential integrity. Delphi raises an exception when an attempt

is made to delete such a parent record.

To effect a cascading delete requires that the deletion of the matching

child records be deleted programmatically -- before the parent record is

deleted. In aa Delphi application, this is done by interrupting the process

of deleting the record in the parent table, deleting the matching records

in the child table (if there are any), and then continuing with the dele-

tion of the parent record.

A record in a table is deleted by a call to the Delete method of the

TTable component, which deletes the current record in the associated

table. Interrupting the this process to first perform some other opera-

tions is a matter creating a procedure associated with the BeforeDelete

event of the TTable. Any commands in a BeforeDelete event procedure are

executed before the call actually goes out from the application to the

Borland Database Engine (BDE) to physically remove the record from the

table file.

To handle the deletion of one or more child records, in a BeforeDelete

event procedure the Delete method for the TTable representing the child

table is called in a loop. The loop is based on the condition of the

record pointer in the taable not being positioned at the end of the data

set, as indicated by the Eof method of the TTable. This also accounts for

there being no child records at all matching the parent record to be

deleted: if there are no matching records, the record pointer will already

be at the end of the data set, the loop condition will evaluate to False,

and the Delete method in the loop never gets executed.

  procedure TForm1.Table1BeforeDelete(DataSet: TDataset);

  begin

    with Table2 do begin

      DisableControls;

      First;

      while not Eof do

        Delete;

      EnableControls;

    end;

  end;

In the above example, the parent table is represented by the TTable comp-

onent Table1 and the child by Table2. The DisableControls and Enable-

Controls methods are used as a cosmetic measure to freeze any data-aware

components that might be displaying data from Table2 while the records

are being deleted. These two methods make the process visually appear

smoother, but aree only optional and not essential to this process. The

Next method need not be called within this loop. This is because the loop

begins at the first record and, as each record is deleted, the record that

previously followed the deleted record moves up in the data set, becoming

both the first and the current record.

This example presumes that the parent and child tables are linked with a

Master-Detail relationship, as is typical for tables for which such

Referntial Integrity is configured. Linking the tables in this manner

results in only those records in the child table that match the current

record in the parent table being available. All other records in the child

table are made unavailable through the Master-Detail filtering. If the

tables are not so linked, there are two additional considerations that

must be accounted for when deleting the child records. The first is that

a call to the First method may or may not put the record pointer on a

record that matches the ccurrent record in the parent table. This necessi-

tates using a search method to manually move the record pointer to a

matching record. The second consideration affects the condition for the

loop. Because records other than those matching the current record in the

parent table will be accessible, the condition for the loop must check

that each record is a matching record before attempting to delete it. This

checking is in addition to querying the Eof method. Because the records

will be ordered by this key field (from a primary or secondary index),

all of the matching records will be contiguous. This leads to the given

that, as soon as the first non-matching record is reached, it can be

assumed that all matching records have been deleted. Thus, the previous

example would be modified to:

  procedure TForm1.Table1BeforeDelete(DataSet: TDataset);

  begin

    with Table2 do begin

      DisableControls;

      FindKey([Table1.Fields[0].AsString])

      while (Fields[0].AsStrring = Table1.Fields[0].AsString) and

        (not Eof) do

        Delete;

      EnableControls;

    end;

  end;

In the above, it is the first field in the parent table (Table1) upon

which the Referential Integrity is based, and the first field in the

child table (Table2) against which matching is judged.


DBASE EXPRESSION INDEXES: A PRIMER

#2025.BDE	From BORLAND

Indexes for dBASE tables may be based on a the values from a single field,

unmodified, or on an expression. Index expressions, unique to dBASE

indexes, may be composed of multiple fields, modifications of field

values, or combinations of these. The expression for a dBASE expression

index is created by using dBASE functions and syntax to concatenate multi-

ple fields or to perform the modifications of field values for fields

included in the index expressions.

Two section are included at the end of this technical article which desc-

ribe the mechanics of creating dBASE expression indexes, one applicable

to doing this in the Database Desktop utility and the other for including

this capability in Delphi applications.

Expression Indexes Based On Multiple Fields

===========================================

dBASE functions are available for use in Delphi or the Database Desktop

for the express use in index expressions, and then only in conjunction

with dBASE indexes. That iis, you cannot use dBASE functions or syntax

to build an index expression for a Paradox or Local InterBase Server

(LIBS) table. Nor can dBASE functions be used in Delphi programming. They

are only available for dBASE expression indexes. The dBASE functions and

syntax that can be used for expression indexes are provided by the Borland

Database Engine (BDE) Dynamic Linked Library (DLL) file IDDBAS01.DLL.

When creating a dBASE index that is to be based on the values from two or

more fields in the table for which the index is being created, the two or

more fields are concatenated (connected together) in a manner similar to

how String type values are concatenated in Delphi syntax: the "+" oper-

ator. For example, the expression needed to create an index that orders

first on a LastName field and then on a FirstName field would be:

  LastName + FirstName

Unlike in dBASE itself, such indexes that are based on multiple fields are

limited to using just those fields in the one  table. dBASE allows the

creation of indexes based on multiple fields contained in different

tables. This is possible only by having the other table open at the time

the index is created or when the table containing the index is used.

With multi-field indexes for other table types (e.g., Paradox and Inter-

Base), the multiple fields are delimited by the semi-colon (;), as in:

  LastName;FirstName

In dBASE expression indexes that concatenate multiple fields, an actual

expression is used:

  LastName + FirstName

When creating index expressions that concatenate two or more fields, all

of the fields included in the index expression must be of the same data

type. Additionally, if they are to be concatenated instead of added

together, the fields must all be of String type. For example, given two

Integer type fields, Value1 and Value2, the index expression...

  Value1 + Value2

...would not cause an error. But then, neither would it concatenate the

two field  values; it would add them together. Thus, if Value1 for a given

record contained 4 and Value2 5, the resulting index node would be an

Integer value of 9, not a String concatenation "45".

If fields to be included in an expression index are not of String type,

they must be converted. Here are some dBASE functions to convert various

data types to String for purposes of creating index expressions:

  STR(<numeric value> [, <width> [, <decimal places>]])

  Converts from either Float or Numeric dBASE types to Character (String)

  DTOS(<date value>)

  Converts Date value to Character, format YYYYMMDD

  MLINE(<memo field>, <line number>)

  Extracts a single line from a memo field as a Character value

Another consideration in creating indexes based on the concatenation of

multiple field is the maximum allowable length of the index value. The

value returned by an index expression may not exceed 100 characters. This

is a limit on the length of the value returned by thee expression, not on

the length of the expression itself. For example, you cannot index on the

concatenation of two fields that both have a length of 255 characters.

Expression Indexes Based On Modifications Of Field Values

=========================================================

In addition to creating indexes based on the concatenation of two or more

field values, it is also possible to construct an index that is based on

a modification of a field value. Examples of this include indexing on just

the first three characters of a String type field, on just the year and

month from a Date field, indexing on a contantenation of a String and Date

field such that the ordering of the String field is ascending but the Date

descending, and even indexing on Boolean field values.

Creating indexes that are based on modifications of field values requires

at least a working knowledge of dBASE functions and syntax -- because the

process uses dBASE, and not Delphi, functions and ssyntax. The dBASE func-

tion SUBSTR() extracts a substring of a String value. The Delphi equiv-

alent for this dBASE function is Copy. But, of these two functions that

serve the same purpose, only SUBSTR() may be used in dBASE index express-

ions.

To use dBASE functions in dBASE index expressions, simply include the

function wherever an index expression is called for, using the approp-

riate dBASE syntax for the function, along with a reference to the

name(s) of the field(s) used in the function. For example, an index expr-

ession based on only the last three characters of a String type field

called Code, that is 20 characters long, would be:

  RIGHT(Code, 3)

Caution should be used in constructing dBASE index expressions that modify

field values to ensure that the resulting expression would return a value

of a consistent length for every record in the table. For instance, the

dBASE TRIM() function removes the trailing blanks (ASCII decimal 32) from

a String type  value. If this were used in conjunction with concatenating

two String fields where the field does not contain values of the same

length for all records, the value resulting from the expression will not

be the same for all records. Case in point, an index expression based on

the concatenation of a LastName and a FirstName field, where the TRIM()

function is applied to the LastName field:

  TRIM(LastName) + FirstName

This expression would not return values of a consistent length for all

records. If the LastName and FirstName fields contained the values...

  LastName FirstName

  -------- ---------

  Smith    Jonas

  Wesson   Nancy

...the result of applying the index expression above would be:

  SmithJonas

  WessonNancy

As can be seen, the length of the value for the first record would be 10

characters, while that for the second 11 characters. The index nodes

created for this index expression would be based on the field values for

the first record encouuntered. This would result in an index node 10 char-

acters long being applied to the field values for all record. In this

example, that would result in the truncation of the expression value for

the second record to "WessonNanc". This would subsequently cause searches

based on the full field value to fail.

The solution to this dilemma would be to not use the TRIM() function so

that the full length of the LastName field, including padding from the

trailing spaces, is used. In indexes that use the IIF() function to order

by one field or another, based on the evaluation of a logical expression

in the IIF(), if the two fields are of different lengths, the shorter

field would need to be padded with spaces to make it the same length as

the longer field. For example, assuming an index that uses the IIF() func-

tion to index either on a Company or a Name field, based on the contents

of Category field, and where the Company field is 40 characters long but

the Name field is 25 chharacters long, the Name field would need to be

padded with 15 spaces; accomplished with the dBASE function SPACE(). That

index expression would then be:

  IIF(Category = "B", Company, Name + SPACE(15))

Searches And dBASE Expression Indexes

=====================================

dBASE expression indexes are exceptions to the norm in how they are

handled by Delphi and the BDE as opposed to how multiple field indexes for

other table types are handled.

This puts such dBASE indexes into a separate class. Handling of such

indexes by Delphi and the BDE is different than those for other table

types. One of these differences is that not all index-based searching

using Delphi syntax can be used with these dBASE expression indexes. The

FindKey, FindNearest, and GotoKey methods of the TTable component cannot

be used with expression indexes. If an attempt to use FindKey is made,

this will result in the error message: "Field index out of range." If the

GotoKey method is ttried, this error message may occur or the record

pointer may just not move (indicating the search value was not found).

Only the GotoNearest method may be used with expression indexes. Even

then, the GotoNearest method may not work with some index expressions.

Experimentation will be needed to see whether the GotoNearest method

will work with a given index expression.

Filtering With dBASE Expression Indexes

=======================================

As with index-based searches, dBASE expression indexes present some

exceptions when using Delphi filtering.

With an expression index active, the SetRange method of the TTable comp-

onent will produce the error: "Field index out of range." However, with

the same expression index active, the SetRangeStart and SetRangeEnd

methods will successfully filter the data set.

For example, with an expression index concatenating a LastName and a

FirstName field active, the code below using the FindKey method (intended

to filter tto just those records where the first character of the LastName

field is "S") will fail with an error:

  begin

    Table1.SetRange(['S'], ['Szzz'])

  end;

Whereas, the code below, with the same expression index active and filter-

ing on the same LastName field, will successfully filter the data and not

incur an error:

  begin

    with Table1 do begin

      SetRangeStart;

      FieldByName('LastName').AsString := 'S';

      SetRangeEnd;

      FieldByName('LastName').AsString := 'Szzz';

      ApplyRange;

    end;

  end;

And, as is the case with index-based searches, with filtering, success of

a filtering attempt will also be dependent on the index expression. The

use of the SetRangeStart and SetRangeEnd methods in the preceeding example

worked with an index that simply concatenated two String type fields. But

if the expression for the index was instead based conditionally on one or

the other fields through use of the IIF() function, the same filtering

routinne would fail (although without an error).

Some Handy dBASE Index Expressions

==================================

Here are some handy dBASE index expressions. Some are readily apparent in

the intended purpose, others are more arcane.

Character field ascending and Date field descending

---------------------------------------------------

With a Character field called Name and a Date field OrdDate:

  Name + STR(OrdDate - {12/31/3099}, 10, 0)

Character field ascending and Numeric (or Float) field descending

-----------------------------------------------------------------

With a Character field called Company and a Numeric field Amount (the

Amount field being 9 digits wide with two decimal places):

  Company + STR(Amount - 999999.99, 9, 2)

Ordering by a Logical field

---------------------------

To have True values appear before False values for a Logical field called

Paid:

  IIF(Paid, "A", "Z")

Two Numeric (or Float) fields

------------------------------

Assuming two Numeric fields with widths of five and two decimal places,

the first field named Price and the second Quantity:

  STR(Price, 5, 2) + STR(Quantity, 5, 2)

Ordering by one field of two, depending on a logical condition

--------------------------------------------------------------

Ordering by the names of months in a Character field

----------------------------------------------------

Assuming a field containing the names of the months ("Jan," "Feb" etc.)

to put the records in proper month order (field named M):

  IIF(M="Jan", 1, IIF(M="Feb", 2, IIF(M="Mar", 3, IIF(M="Apr", 4,

  IIF(M="May", 5, IIF(M="Jun", 6, IIF(M="Jul", 7, IIF(M="Aug", 8,

  IIF(M="Sep", 9, IIF(M="Oct", 10, IIF(M="Nov", 11, 12)))))))))))

(The above is a single expression line, broken into multiple lines here

due to page width.)

Ordering by the first line of a memo field

------------------------------------------

For a memo field named Notes:

  MLINE(Notes, 1)

Ordering by the middle three characters in a nine character long field

----------------------------------------------------------------------

For a nine character long field called StockNo:

  SUBSTR(StockNo, 4, 3)

Creating dBASE Expression Indexes In Database Desktop

=====================================================

In the Database Desktop utility, indexes may be created for a table either

duting the process of creating a new table or by restructuring an existing

table. In both cases, the Define Index dialog is used to create one or

more indexes for the table used.

To get to the Create Index dialog while creating a new table, in the

Create dBASE Table dialog (showing the structure), from the Table Proper-

ties listbox select "Indexes" and click the Define button.

To get to the Create Index dialog to create an index for an existing

table, select Utilities|Restructure, select the table file from the Select

File dialog, and in the Restructure dBASE Table diallog (showing the table

structure) from the Table Properties listbox select "Indexes" and click

the Define button.

Once in the Create Index dialog, expression indexes can be created by

clicking the Expression Index button and entering the expression to be

used in the Expression Index entry field. To assist in this process, you

can double-click on a field name in the Field List listbox and that field

name will be inserted into the Index Expression entry field at the current

insertion point (caret position).

Once the index expression has been entered, click the OK button. Enter the

name of the new index tag in the Index Tag Name entry field on the Save

Index As dialog and click OK. (Remember, dBASE index tag names cannot

exceed ten characters in length and must abide by the normal dBASE naming

conventions.)

Creating dBASE Expression Indexes In Delphi Applications

========================================================

dBASE indexes can be created programmatically iin Delphi applications,

either as a new table is being created (CreateTable method of the TTable

component) or by adding an index to an existing table.

Creating an index as part of a new table being created is a matter of

calling the Add method for the IndexDefs property of the TTable. A special

consideration that the index options must include the option ixExpression.

This index option is unique to dBASE indexes, and should only be used with

dBASE expression indexes. For example:

  with Table1 do begin

    Active := False;

    DatabaseName := 'Delphi_Demos';

    TableName := 'CustInfo';

    TableType := ttdBASE;

    with FieldDefs do begin

      Clear;

      Add('LastName', ftString, 30, False);

      Add('FirstName', ftString, 20, False);

    end;

    with IndexDefs do  begin

      Clear;

      Add('FullName', 'LastName + FirstName', [ixExpression]);

    end;

    CreateTable;

  end;

Adding an index to an existing table is accomplished by calling the Add--

Index method of the TTable. Again, the index options must include the

TIndexOptions value ixExpression.

  Table1.AddIndex('FullName', 'LastName + FirstName', [ixExpression]);

Learning More About dBASE Functions And Syntax

==============================================

Only dBASE functions and syntax that apply to data manipulation can be

used to construct a dBASE expression index. However, it is beyond the

scope of this technical article to fully list and describe all of these

functions. To learn more about dBASE data manipulation functions, the user

is advised to consult the dBASE Language Reference manual or one of the

many third-party dBASE books.


REMOVING THE VERTICAL SCROLLBAR FROM A TDBGRID

#2026.BDE	From BORLAND

{

 In order to remove the vertical scrollbar from a TDBGrid component,

 you must override its Paint method.  Inside the Paint method you

 must call the SetScrollRange API procedure to set the min and max

 scroll values to zero (this disables the scrollbar), and then call

 the inherited Paint.  The code below is a unit containing a new

 component called TNoVertScrollDBGrid that does this.  You can copy

 the code into a file called NEWGRID.PAS, and add it to the component

 library as a custom component.

}

unit Newgrid;

interface

uses

  WinTypes, WinProcs, Classes, DBGrids;

type

  TNoVertScrollDBGrid = class(TDBGrid)

  protected

    procedure Paint; override;

  end;

procedure Register;

implementation

procedure TNoVertScrollDBGrid.Paint;

begin

  SetScrollRange(Self.Handle, SB_VERT, 0, 0, False);

  inherited Paint;

end;

procedure Register;

begin

  RegisterComponents('Data Controls', [TNoVertScrollDBGrid]);

end;

end.


INTERBASE BLOB FIELDS: A PRIMER

#2027.BDE	From BORLAND

InterBase BLOB fields are not all the same. They actually consist in a

variety of forms, or sub-types of the general BLOB type. Knowing which

sub-type of BLOB field to use when is essential to creating database appl-

ications that incorporate InterBase BLOB fields. BLOB fields come in three

varieties: sub-type 0 and sub-type 1 (the two predefined sub-types), and

user-defined sub-types.

Sub-type 0 BLOB fields are the type created when a CREATE command is

issued and a sub-type is not specified. For clarity in SQL syntax, though,

it is possible to explicitly indicate that the BLOB field is to be of sub-

type 0. This sub-type of BLOB field is for the storage of binary data.

InterBase makes no analysis of the data stored, it just stores it in the

BLOB field on a byte-for-byte basis. The most common intended use for BLOB

fields in Windows applications is the storage of bitmap binary data, typi-

cally for display in a TDBImage component. Either the BLOB field sub-type

0 or a uuser-defined sub-type BLOB field will work for this purpose.

The second predefined sub-type is 1. This BLOB field sub-type is designed

for the storage of text. Typically, this is the free-form memo or notes

data displayed and edited with the TDBMemo component. This BLOB field sub-

type is better for storing text data than the VARCHAR field because,

unlike with the VARCHAR field, there is no design-time limit placed on the

storage capacity of the field.

In SQL syntax, the sub-type 1 BLOB field is created by following the BLOB

field type keyword with the SUB_TYPE keyword and the integer one:

  CREATE TABLE WITHBLOB

  (

    ID CHAR(3) NOT NULL PRIMARY KEY,

    MEMO BLOB SUB_TYPE 1,

    AMOUNT NUMERIC

  )

Aside from the two predefined BLOB field sub-types, there are user-defined

sub-types. User-defined sub-types are designated by a negative integer

value in association with the SUB_TYPE keyword. The actual integer value,

as long as it is negative, is actually arbitrary and up to the discretion

of the table creator. A designation of -1 is functionally the same as that

of a -2. The only consideration when using user-defined sub-types is

ensuring that the same type of binary data is stored for every row in the

table for a BLOB field of a given user-defined sub-type. InterBase will

not evaluate whether this criteria is met, and it is the responsibility of

the application inserting the binary data to store the appropriate type of

data. No error will occur from the InterBase side if an incorrect type of

binary data is stored in a user-defined BLOB field sub-type, but an appl-

ication can incur difficulties if it is expecting one type of data but

encounters another.

A BLOB field of a user-defined sub-type is created with the SQL syntax

such as that below:

  CREATE TABLE IMAGE_DATA

  (

    FILENAME CHAR(12) NOT NULL PRIMARY KEY,

    BITMAP BLOB SUB_TYPE -1,

    EXEs BLOB SUB_TYPE -2,

  )

When using a table created with the abovee command, the field BITMAP would

only be used to store one distinct type of binary data for all records. In

this case, bitmap data. The field EXEs implies the storage of executable

files loaded from disk. If an application using this table were to mis-

takenly store binary data that should have been in the EXEs field into the

BITMAP field, InterBase would generate no errors, but the application

would have extreme difficulties displaying a stored executable file in a

TDBImage component.

InterBase BLOB fields and Delphi

--------------------------------

When defining TField objects for InterBase BLOB fields in Delphi, the

various BLOB field sub-types are assigned TField derivative types as

follows:

  Sub-type 0:   TBlobField

  Sub-type 1:   TMemoField

  User-defined: TBlobField

Because both the predefined sub-type 0 and user-defined sub-types are

recognized as TBlobField objects, care must be taken when designing an

application to not mistake a field of one subb-type for that of another.

The only way to differentiate between a field of sub-type 0 from that of

a user-defined type is by viewing the metadata information for the table,

which cannot be done from within Delphi. The Local InterBase Server

utility WISQL can be used to view table metadata.

InterBase BLOB fields and Database Desktop

------------------------------------------

The Database Desktop utility that comes with Delphi (DBD) does not create

user-defined subtypes. When using BLOB fields created in Database Desktop,

use the "BLOB" field type for binary data, including bitmap data. This

creates a BLOB field of the predefined sub-type 0.

The DBD also offers a BLOB field type TEXT BLOB. This is equivalent to the

pre-defined subtype 1, and should be used where free-form text storage

will be needed. While it is functionally equivalent to the pre-defined

subtype 1 BLOB field, it will appear with a slightly different type des-

ignation if you view the metadata for the table in the WISQL utility.


USING THE ASCII DRIVER WITH COMMA-DELIMITED FILES

#2028.BDE	From BORLAND

Delphi (and the BDE) has the capability to use ASCII files to a limited

degree as tables. The ASCII driver has the capability to translate the

data values in an ASCII fixed-length field or a comma-delimted file into

fields and values that can be displayed through a TTable component. How

this translation of the ASCII file takes place depends on an accompanying

schema file. The schema file for an ASCII data file defines various attri-

butes necessary for parsing the ASCII data file into individual field

values. The field definitions for an ASCII fixed-length field file is

relatively straightforward, the offsets of various fields in the ASCII

file being consistent across all rows in the file. However, for comma-

delimited files, this process is slightly more complicated due to the

fact that not all data values in such a file may be the same length for

all rows in the file. This article, then, concentrates on this more

difficult task of reading data from comma-delimited, or varrying-length

field, files.

The Schema File

===============

The schema file for an ASCII data file contains information that defines

both the file type (comma-delimited versus fixed-length field), as well as

defining the fields that are represented by the data values in each row of

the ASCII data file. (All of the settings used in a schema file are case

insensitive, so "ascii" is just as valid as "ASCII".) In order that a

schema file be recognized as such, it must have the same filename as the

ASCII data file for which it provides definitions, but with the filename

extension .SCH (for SCHema). The attributes that describe the file are:

  File name: Enclosed in square brackets, this setting specifies the

             name of the ASCII data file (sans the filename extension,

             which must be .TXT).

  Filetype:  Specifies whether the ASCII data file is structured as a

             fixed-length field file (use a setting of FIXED) or a comma-

             deelimited file (with data values of potentially varying

             length (use a setting of VARYING).

  Delimiter: Specifies the character that surrounds String type data val-

             ues (typically, the double quotation mark, ASCII decimal 34).

  Separator: Specifies the character that is used to separate individual

             data values (typically, a comma). This character must be a

             visible character, i.e., cannot be a space (ASCII decimal

             32).

  CharSet:   Specifies the language driver (use a setting of ASCII).

Following the file definition settings are field definitions, one for each

data value on each row of the ASCII data file. These field definitions

supply the information Delphi and the BDE will need to create a virtual

field in memory to hold the data value, that virtual field's data type

which will affect how the value is translated after being read from the

ASCII file, and size and positioning attributes. The various seettings that

will appear in each field definition are:

  Field:              Virtual field name, will always be "Field" followed

                      by an integer number representing that field's ord-

                      inal position in respect to the other fields in the

                      ASCII data file. E.G., the first field is Field1,

                      the second Field2, and so on.

  Field name:         Specifies the display name for the field, which

                      appears as the column header in a TDBGrid. Naming

                      convention for ASCII table fields follows that for

                      Paradox tables.

  Field type:         Specifies the data tyoe BDE is to use in translating

                      the data value for each field and tells Delphi what

                      type of virtual field to create.

                      Use the setting For values of type

                      --------------- ----------------------

                      CHAR            Character

                      FLOAT           64-bit floating point

                      NUMBER          16-bit integer

                      BOOL            Boolean (T or F)

                      LONGINT         32-bit long integer

                      DATE            Date field.

                      TIME            Time field.

                      TIMESTAMP       Date + Time field.

                      (The actual format for date and time data values

                      will be determined by the current setting in the BDE

                      configuration, Date tab page.)

  Data value length:  Maximum length of a field's corresponding data

                      value. This setting determines the length of the

                      virtual field that Delphi creates to receive values

                      read from the ASCII file.

  Number of decimals: Applicable to FLOAT typpe fields; specifies the

                      number of digit positions to the right of the deci-

                      mal place to include in the virtual field defini-

                      tion.

  Offset:             Offset from the left that represents the starting

                      position for the field in relation to all of the

                      fields that preceed it.

For example, the field definition below is for the first field in the

ASCII table. It defines a String type data value with a name of "Text",

a maximum data value length of three characters (and the field will

appear as only three characters long in Delphi data-aware components such

as the TDBGrid), no decimal places (a String data value will never have

any decimal places), and an offset of zero (because it is the first field

and there would not be any preceeding fields).

  Field1=Text,Char,3,00,00

Here is an example of a schema file with three fields, the first of String

type and tthe second and third of type date. This schema file would be

contained in a file named DATES.SCH to provide file and field definitions

for an ASCII data file named DATES.TXT.

  [DATES]

  Filetype=VARYING

  Delimiter="

  Separator=,

  CharSet=ascii

  Field1=Text,Char,3,00,00

  Field2=First Contact,Date,10,00,03

  Field3=Second,Date,10,00,13

This schema defines a comma-delimited field where all String type data

values can be recognized as being surrounded by the double quotation mark

and where distinct data values are separated by commas (excepting any

commas that may appear within the specified delimiter, inside individual

String data values). The character field has a length of three characters,

no decimal places, and an offset of zero. The first date field has a

length of 10, no decimals, and an offset of three. And the second date

field has a length of 10, no decimals, and an offset of 13.

For reading ASCII comma-delimited files, the length and offset parameteers

for the field definitions do not apply to data values in the ASCII files

(as is the case for fixed-length field files), but to the virtual fields,

defined in the application, into which the values read will be placed. The

length parameter will need to reflect the maximum length of the data value

for each field -- not counting the delimiting quotation marks or the comma

separators. This is most difficult to estimate for String type data values

as the actual length of such a data value may vary greatly from row to row

in the ASCII data file. The offset parameter for each field will not be

the position of the data value in the ASCII file (as is the case for

fixed-length field files), but the offset as represented by the cumulative

length of all preceding fields (again, the defined fields in memory, not

the data values in the ASCII file.

Here is a data file that would correspond to the schema file described

above, in a file named DATES.TXT:

  "A",08/01/1995,08/11/19955

  "BB",08/02/1995,08/12/1995

  "CCC",08/03/1995,08/13/1995

The maximum length of an actual data value in the first field is three

("CCC"). because this is the first field and there are no preceding

fields, the offset for this field is zero. The length of this first field

(3) is used as the offset for the second field. The length of the second

field, a date value, is 10, reflecting the maximum length of a data value

for that field. The accumulated length of the first and second fields are

then used as the offset for the third field (3 + 10 = 13) .

It is only when the proper length for the data values in the ASCII file

are used and each fields length added to any preceding fields to produce

offset values for succeeding fields that this process will correctly read

the data. If data is misread because of improper length settings in the

schema file, most values will suffer adverse translation effects, such

as truncation of character data or numeric values being interprreted as

zeros. Data will usually still be displayed, but no error should occur.

However, values that must be in a specific format in order to be trans-

lated into the appropriate data type will cause errors if the value read

includes characters not valid in a date value. This would include a date

data value which, when incorrectly read may contain extraneous characters

from other surrounding fields. Such a condition will result in a data

translation exception requiring an adjustment of the field length and

offset settings in the schema file.


DETERMINING RECORD NUMBER IN A DBASE TABLE

#2033.BDE	From BORLAND

dBASE tables employ a fairly static record numbering system. The record

number for a given record reflects its physical position in the table

file. These record number are not subject to change dependent on the

filtering of data or index ordering. For instance, a record that is the

first record stored in the .DBF file would be record number 1. It is

possible that, through the ordering of an index, this record may be

displayed as the last of 100 records. In such a case, its record would

remain the same -- one -- and would not be changed to 100 to reflect its

position in the index ordered data set. This is in contrast with Paradox

tables, where there is a sequence number. The Paradox sequence number is

like the dBASE record number except that it is much more fluid and the

number for a given record will reflect its position relative to the data

set. That is, a record may not always have the same sequence number given

filtering of the data set to reduce the number of records orr when an index

is active that may change the displayed order of the record.

In database applications created with Delphi and the Borland Database

Engine (BDE), there is no provision built into the stock data components

for extracting or determining the record for dBASE tables. Such an opera-

tion is, however, possible by making a call from the application a BDE

function.

There are a number of BDE functions that will return information about the

current dBASE record, such as the record number. Basically, any function

that fills a BDE pRECProps structure would suffice. Such BDE functions

include DbiGetRecord, DbiGetNextRecord, and DbiGetPriorRecord. Of course,

only the first of these functions really applies to retrieving information

about the current record. The other two move the record pointer when in-

voked, similar in effect to the Next and Prior methods of the TTable or

TQuery components.

The pRECProps structure consists of the fields:

  iSeqNum: type LongInnt; specifies the sequence number of the record

    (relative to the data set, including filtering and index ordering);

    applicable if the table type supports sequence numbers (Paradox only).

  iPhyRecNum: type LongInt; specifies the record number for the record;

    applicable only when the table type supports physical record numbers

    (dBASE only).

  bRecChanged: type Boolean; not currently used.

  bSeqNumChanged: type Boolean; not currently used.

  bDeleteFlag: type Boolean; indicates whether the record is deleted;

    applicable only for table types that support soft-deletes (dBASE

    only).

One of these BDE functions may be invoked in a Delphi application to fill

this structure, from which the physical record number may be retrieved.

Below is an example of the DbiGetRecord function used for this purpose.

  function RecNo(ATable: TTable): LongInt;

  var

    R: RECProps;

    rslt: DbiResult;

    Error: array [0..255] of Char;

  begin

    ATable.UUpdateCursorPos;

    rslt := DbiGetRecord(ATable.Handle, dbiNoLock, nil, @R);

    if rslt = DBIERR_NONE then

      Result := R.iPhyRecNum

    else begin

      DbiGetErrorString(rslt, Error);

      ShowMessage(StrPas(Error));

      Result := -1;

    end;

  end;

As with invoking any BDE function in a Delphi application, the BDE wrapper

units DbiTypes, and DbiErrs, DbiProcs must be included in the Uses section

of the unit in which the BDE function will be invoked (the Uses section

not shown here). To make this function more transportable, it does not

reference the subject TTable component directly, but a reference to the

TTable is passed as a parameter. If this function is used in a unit that

does not reference the Delphi units DB and DBTables, they must be added so

that references to the TTable component will be valid.

The UpdateCursorPos method of the TTable is called to ensure that the

record number current in the TTable component is synchronized with that

of thee underlying table.

BDE functions do not in themselves cause an exception if they fail.

Rather, they return a value of BDE type DbiResult that indicates the succ-

ess or failure of the intended operation. This return value must then be

retrieved and evaluated by the front-end application, and the appropriate

action taken. A result other than DBIERR_NONE indicates an unsuccessful

execution of the function. An extra step may be taken (as in the example

above) to query the BDE to translate an error code into a readable mess-

age with the BDE function DbiGetErrorString. In this example, the return

value from the invoking of DbiGetRecord is stored in the variable rslt,

and then compared against DBIERR_NONE to determine the success of the

function call.

If the call to DbiGetRecord succeeds, the physical record number from the

iPhyRecNum field of the pRECProps structure is stored to the variable

Result, which is the function's return value. To indicate when the

function hass failed (i.e., the involing of the DbiGetRecord function

failed), a value of negative one is returned instead of the record

number. This value is purely arbitrary, and any value of a compatible

type may be used at the discretion of the programmer.


REDISTRIBUTING THE BORLAND DATABASE ENGINE (BDE), PART 2

#2079.BDE	From UNKNOWN

Problem

When programming database applications in Borland Delphi, the program will not

start, unless the Borland Database Engine is installed. Furthermore, Borland

redistributes the Borland Database Engine only with their own installation

program, which is unsuitable if only one set of installation disks is wanted for

your self-made program.

How BDE installs itself

The Borland Database Engine installs itself into a specified directory. The

default is C:\IDAPI, and all files are put in this directory or in sub directories.

Furthermore it adds settings to WIN.INI as follows:

[IDAPI]

DLLPATH=C:\idapi

CONFIGFILE01=C:\IDAPI\IDAPI.CFG

[Borland Language Drivers]

LDPath=C:\IDAPI\LANGDRV

You might think that CONFIGFILE01 refers to the first configuration file of many,

but unfortunately, this is not the case.

How to install BDE from your application

You must use two .EXE files. The first .EXE file may not use any database units

(DB, DBTables, DBCtrls), since these units require the BDE to be installed prior

to running the .EXE file. This first file must check for the presence of BDE and

alert the user, if BDE is not installed. An easy way to do this is:

var

  WinDir:string;

function GetWindowsDirectory:string;

begin

  If WinDir='' then

    raise Exception.Create ('Could not retrieve Windows directory.');

  Result:=WinDir;

end;

function IsInstalledBDE:boolean;

var

  f:TIniFile;

begin

  f:=TIniFile.Create (GetWindowsDirectory+'\win.ini');

  Result:=f.ReadString('IDAPI','DLLPATH','')<>'';

  f.Free;

end;

procedure CheckForBDE;

begin

  if not IsInstalledBDE then begin

    Application.MessageBox (`Error!', `You must install the `+

      'Borland Database Engine '+

      'prior to running this program.', MB_OK+MB_ICONEXCLAMATION);

    raise Exception.Create (`Borland Database Engine is not installed');

  end;

end;

begin

  WinDir[0]:=char(WinProcs.GetWindowsDirectory (@WinDir[1],255));

end.

If you use an installation program, like Microsoft Setup, you must add all the

files in the C:\IDAPI directory and sub directories to the installation diskettes.

The setup program must end with adding the lines mentioned in the previous

paragraph to the WIN.INI file, like this:

procedure AutoRegistration;

var

  WinINI:TIniFile;

  Buffer:string;

begin

  WinINI:=TIniFile.Create (GetWindowsDirectory+'\Win.ini');

  try

    WinINI.WriteString ('IDAPI','DLLPATH','C:\idapi');

    WinINI.WriteString ('IDAPI','CONFIGFILE01','C:\IDAPI\IDAPI.CFG');

    WinINI.WriteString ('Borland Language Drivers','LDPath','C:\IDAPI\LANGDRV');

  finally

    WinINI.Free;

  end;

end;

In order to add your own aliases (try to avoid these!), or worse, your own ODBC

drivers, you must either exchange the IDAPI.CFG file, or make the WIN.INI file

point to another IDAPI.CFG file. The easiest way is to make WIN.INI point to

another file, which makes one of the lines above look like this:

WinINI.WriteString ('IDAPI','CONFIGFILE01','C:\MYAPP\IDAPI.CFG');

Here, C:\MYAPP is the directory of your self-made application. The IDAPI.CFG file in this directory can be copied to the hard disk by your installation program.


[Q] about a caption (simple question)

#510.BDE	From KWolak@mail.cbf.com Tue Dec 12 14:01:34 1995

On 6 Dec 1995 12:12:01 GMT, Vezass Amsterdam <vezass@xs4all.nl> wrote:

>I have a table (or an array) with several titles. I want the caption

>of a form to come from the table (or array). Something like:

>

>       form1.caption = table->title_a

Assuming that the "table" above is the name of a TTable component connected

to a table and "title_a" is the name of a String type field, the syntax

would need to look like:

  Form1.Caption := Table.FieldByname('title_a').AsString;

**************************************************************************

Steve Koterski

Product Group Manager

Delphi Technical Support

Borland International, Inc.


Cost of Client Server Edition

#1000.CS	From: koterski@genghis (Steve Koterski)

Susan Margarit (smargari@NMSU.EDU) wrote:

: Am I confused or do I really have to shell out another $1700 for the

: c/s version in order to have more than one user access a database

: developed in Delphi? I have a sssslllloooowww multiuser scheduling app

: that I developed with VB/access that I want to convert to Delphi but I

: won't spend that much extra to go from one user to two. Is this the

: case?

Maybe...but probably not. What you are referring to is the Enterprise

(client-server) version of Delphi. That is needed for using SQL tables

on an SQL server.

But if you are going to use dBASE or Paradox tables, you will not need

the client-server access. The Borland Database Engine (BDE) will suffice,

including multi-user access to those tables in an application. The BDE

may be freely distributed with the app, no royaltees. This capability

(the BDE) is available in both the Enterprise and Desktop versions of

Delphi.

You can use other types of local tables through ODBC as an alternative to

the native file formats.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

From: joser@news.dorsai.org ()

Subject: Re: Delphi- Clear something up for me.

Date: Wed, 22 Mar 1995 14:09:50 GMT

Susan Margarit (smargari@NMSU.EDU) wrote:

: Am I confused or do I really have to shell out another $1700 for the

: c/s version in order to have more than one user access a database

: developed in Delphi? I have a sssslllloooowww multiuser scheduling app

: that I developed with VB/access that I want to convert to Delphi but I

: won't spend that much extra to go from one user to two. Is this the

: case?

: Jim Margarit (smargari@nmsu.edu)

Yes you are confused, 1.- you can have anyt application(delphi) using the

Paradox/Dbase (DBE) database engion of any ODBC compliant database and beeing

a multiuser application on a Novel/Lantastic.... network.  the CS has

something to do with the Iterbase server. In the standard version you get

a single version (local) of Interbase while in the CS is an unlimited version

plus some other goddies (I don't really know all the details)

One thing is for sure, You can develop and use multiuser database apps

with the standard version of Delphi

Hope this helps.

--

Jose R. Nebro

joser@dorsai.org

       /////  ///////  //      //

        /    //   //  //\     //

       /    //////   // \    //

      /    // \     //   \  //

  ////    //   \   //     \//

From: dmmatt@ccmail.monsanto.com (D.M. (Mike) Mattix)

Subject: Re: Delphi- Clear something up for me.

Date: Wed, 22 Mar 1995 08:57:36 LOCAL

In article <3knooc$mec@druid.borland.com> koterski@genghis (Steve Koterski)

writes:

>Susan Margarit (smargari@NMSU.EDU) wrote:

>: Am I confused or do I really have to shell out another $1700 for the

>: c/s version in order to have more than one user access a database

>: developed in Delphi? I have a sssslllloooowww multiuser scheduling app

>: that I developed with VB/access that I want to convert to Delphi but I

>: won't spend that much extra to go from one user to two. Is this the

>: case?

>Maybe...but probably not. What you are referring to is the Enterprise

>(client-server) version of Delphi. That is needed for using SQL tables

>on an SQL server.

>But if you are going to use dBASE or Paradox tables, you will not need

>the client-server access. The Borland Database Engine (BDE) will suffice,

>including multi-user access to those tables in an application. The BDE

>may be freely distributed with the app, no royaltees. This capability

>(the BDE) is available in both the Enterprise and Desktop versions of

>Delphi.

>You can use other types of local tables through ODBC as an alternative to

>the native file formats.

Actually, if you use ODBC to a Mid/MainFrame Database Server you can use the

desktop version to develop Multi-User Client/Server app.  ODBC does not care

if the Data Source it connects to is local or remote, FoxPro or Oracle.  As I

understand it the Client/Server version of Delphi provides the BDE native

drivers for SQL Server, Oracle, etc which would/should make it faster than

ODBC access for those databases.  The Client/Server version also is reported

to provide the VCL source.

Just clarifying a point.

Mike (who is accessing DEC/Oracle Rdb via ODBC from Delphi)

D.M.(Mike) Mattix

Mail: dmmatt@ccmail.monsanto.com

Organization: Ag Group of Monsanto

              Luling, LA 70070

From: smargari@NMSU.EDU (Susan Margarit)

Subject: Re: Delphi- Clear something up for me.

Date: 24 Mar 1995 02:51:02 GMT

joser@news.dorsai.org wrote:

: Susan Margarit (smargari@NMSU.EDU) wrote:

: : Am I confused or do I really have to shell out another $1700 for the

: : c/s version in order to have more than one user access a database

: : developed in Delphi? I have a sssslllloooowww multiuser scheduling app

: : that I developed with VB/access that I want to convert to Delphi but I

: : won't spend that much extra to go from one user to two. Is this the

: : case?

: : Jim Margarit (smargari@nmsu.edu)

: Yes you are confused, 1.- you can have anyt application(delphi) using the

: Paradox/Dbase (DBE) database engion of any ODBC compliant database and

beeing

: a multiuser application on a Novel/Lantastic.... network.  the CS has

: something to do with the Iterbase server. In the standard version you get

: a single version (local) of Interbase while in the CS is an unlimited

version

: plus some other goddies (I don't really know all the details)

: One thing is for sure, You can develop and use multiuser database apps

: with the standard version of Delphi

: Hope this helps.

: --

: Jose R. Nebro

: joser@dorsai.org

:        /////  ///////  //      //

:         /    //   //  //\     //

:        /    //////   // \    //

:       /    // \     //   \  //

:   ////    //   \   //     \//

Thanks for the replies. In reading the docs, and I don't mean this as

another docs flame, the words 'single user, local database' etc are

used liberally in association with BDE.'Multiuser' is never used. No

docs on record locking schemes, no docs on error returns to look for

when you can't lock a record someone else is using, no hints on

preventing deadly embraces, no hint whatsoever that it can be used by

more than one simultaneous user. I was getting positively paranoid

trying to figure this out from the docs.

Jim Margarit


Referencing SENDER object in Delphi

#1000.OOP	From: james.obrien@yale.edu (James A. O'Brien)

>I'm pretty new to object-Pascal...  how to I reference the Sender object

>in the event handlers?  For example, how would I get at the Text property?

>   txt:=Sender.Text; {doesn't work}

Either a)

with Sender as TEdit do

  txt := text;    {Will raise an exception if sender isn't a TEdit}

or b)

if (Sender is TEdit) then

  txt := TEdit(sender).text;

Jim.

From: jeroenp@dragons.nest.nl (Jeroen Pluimers)

Monday March 06 1995 22:20, rm_savard@pnl.gov wrote:

 rsg> I'm pretty new to object-Pascal...  how to I reference the Sender object

 rsg> in the event handlers?  For example, how would I get at the Text

 rsg> property?

 rsg>    txt:=Sender.Text; {doesn't work}

Try this:

   Txt := (Sender as TButton).Text

This is a typecase with implicit type-checking (by means of Run Time Type

Information or RTTI). If your Sender is not a subclass of TButton, then you

get

an exception telling you. After that, your app continues to run normally.

Jeroen

From: The Green Meddler <kilgalen@tde.com>

rm_savard@pnl.gov (Rodney M Savard) wrote:

>

> In article <3ji0rd$9vd@tdelx01.tde.com>, The Green Meddler

<kilgalen@tde.com> says:

>

> >> I'm pretty new to object-Pascal...  how to I reference the Sender object

> >> in the event handlers?  For example, how would I get at the Text

property?

> >>

> >>    txt:=Sender.Text; {doesn't work}

>

> >you have to do a typecast. sender will be an object of some type,

> >so you say txt := SOMEOBJECT( Sender ).Text.

>

> Thanks, I found out I could do this and it worked:

>

>    txt:=(Sender as TEdit).Text;

>

> which is similar to what you suggested. Is there any way I can make

> this work for ANY object with a text property instead of just one?

>

> -------------------------------------------------------------------------

> Rodney M. Savard                                        rm_savard@pnl.gov

> Kennewick, Tri-Cities, WA                                       Get NTed!

i stand ashamed! (blush)

despite five months of working with delphi, i still forget to use

as/is, and they are POWERFUL!

as far as i know, you can use AS/IS on anything provided that

you know what it really is; ie if the information in the object

can't be coerced properly, you'll either fail or get an exception.

for example, you could send a memo instead of a tedit and still

get its text property, but trying to coerce a tedit to a memo

should fail.

GM

From: higgins@cs.niu.edu (Greg Higgins)

In article <3jptvu$i9@tdelx01.tde.com>,

The Green Meddler  <kilgalen@tde.com> wrote:

>

>as far as i know, you can use AS/IS on anything provided that

>you know what it really is; ie if the information in the object

>can't be coerced properly, you'll either fail or get an exception.

>

>for example, you could send a memo instead of a tedit and still

>get its text property, but trying to coerce a tedit to a memo

>should fail.

>

Being an old warhorse as it were, there's a part of me which thinks

EVERY event handler should start off with

if sender.classname = 'SomeClassName' then

  with sender as SomeClassName do

...

else

  ShowMessage ( 'Your pgmr messed up. Sorry' );

Based on what I've seen however, this isn't done much. So how are

we guaranteed that the TObject we're working with is the one

we meant to be working with ( or the class of things we meant

to affect ).

On a related issue, does any one have a one step method for

getting to the manual page for TObject? Right now I

Search Object -> See Also -> Object Types -> See Also -> TObject

which ages me.

-- greg

  higgins@happmis.com

From: memorex@cats.ucsc.edu (Mathew Gyokers Eliot)

        define a bookmark, it'll take you right to it.

--

Beavis kicks ASS! He KICKS 'em! Kicks, KICKS!  He rules, he RULES, RULES!!

From: james.obrien@yale.edu (James A. O'Brien)

In article <3juu17$c1h@mp.cs.niu.edu> higgins@cs.niu.edu (Greg Higgins)

writes:

>Based on what I've seen however, this isn't done much. So how are

>we guaranteed that the TObject we're working with is the one

>we meant to be working with ( or the class of things we meant

>to affect ).

>-- greg

>  higgins@happmis.com

If it's not, an EInvalidCast (I think) exception will be raised.  You can

handle that, if you like.

Jim.

From: higgins@cs.niu.edu (Greg Higgins)

In article <3k11k1$2l2@nic.scruz.net>, Jon Shemitz  <jon@armory.com> wrote:

>higgins@cs.niu.edu (Greg Higgins) wrote:

>

>> On a related issue, does any one have a one step method for

>> getting to the manual page for TObject? Right now I

>> Search Object -> See Also -> Object Types -> See Also -> TObject

>> which ages me.

>

>Search for TObject doesn't work?

>

You have to use search all, not plain search.

-- greg

  higgins@happmis.com


Delphi and WM_xxx Handling.

#1001.OOP	From: Chuck Jazdzewski <cjaz@borland.com>

dhatlestad@aol.com (DHatlestad) wrote:

>

> >>The call to "inherited" is important.

>

> Do you always call Inherited? For example, if I handle WM_SYSCOMMAND...

No.  If you want to squelch the inherited behavior you shouldn't call

it.  It is not that expensive to call inherited so I would call it

event if you are sure the inherited doesn't do anything since it

might in the next release and your control would stop working.

Chuck Jazdzewski (cjaz@borland.com)

Delphi Development

From: The Green Meddler <kilgalen@tde.com>

muftiteg@netcom.com wrote:

>

> Oh, wotta program.  I'm loving it.

>

> Anywho, on to the subject.  I would like to be able to have

> certain windows/components respond to certain obscure messages.

> For example, one message that I need to respond to is the

> WM_WININICHANGE.  Any tips would really be useful.

>

look up the application.onmessage method. it's the way to get

all the message in the delphi message-handling environment. it's

sort of a delphi version of WINMAIN. the docs aren't entirely

clear, but remember to set the Handled property to true if you

process a message.

> Been outta Pascal for a lotta years (since Turbo v4.0).  I got

> seduced by the dark side (c++/asm).  Am actually enjoying Pascal.

> Scary.  Loved C/C++ for a long while, but am really sick of it

> lately, like the last four days.  Like ever since Delphi.  I

> don't understand.  Scary.

>

> Thanx.

>

>   -- Mufti

>

it's okay. support groups ARE available. :)

GM


Delphi Pascal Language

#1002.OOP	From: dmurdoch@mast.queensu.ca (Duncan Murdoch)

In article <3jvjc7$4j6@engr.orst.edu> budd@ada.CS.ORST.EDU (Tim Budd) writes:

>I have a few questions about the Object Pascal language as implemented in

>Delphi.  Is it similar to Turbo Pascal, or to Apple's original Object Pascal,

>or to the new ANSI proposed Object Pascal (see Dec 1994 SigPlan notices for

>a description of the latter).  Specifically, does the language

>support / require constructors and destructors?  How about multiple

>inheritance?  Views?  Abstract classes?

 Constructors and destructors required.

 Multiple inheritance not supported.

 Views not supported.

 I'm not sure about abstract classes, because I don't know what they are.

It's closely based on the Turbo Pascal object model.  The main change is that

they've moved to a reference model (like ANSI).  They've put a base class

into the language (like ANSI), but I think the base class name and the

methods it contains are different from the ANSI proposal.  They've put

support for abstract methods into the language, but unlike ANSI, you can make

an instance of a class without defining all of the methods -- you'll get a

run-time error if you call an abstract one.

There are also 2 new classifications of methods.  Besides public and private,

they can be published (available to the run-time type info system) and

protected (only visible to descendants).

Duncan Murdoch


Can Delphi build OCXs?

#1003.OOP	From: Tom Cabanski <sig@teleport.com>

bglover@netcom.com (William Glover) wrote:

>

> OK, here is a question. I have listened to the praises of Delphi,

> so can you build an OCX in Delphi or is it limited to just the

> VCLs used by Delphi?

Yes, Delphi can do anything C can in terms of Windows development.

Delphi DOES NOT include wizards or OOP framework to help developers

build OCX or VBX controls.  Grapevine says Delphi will include

OCX support (perhaps that includes OCX development support) in

the post Windows 95 (90 days after Windows 95 ships).

For now, stick with Microsoft C for OCX development.


OLE Automation in DELPHI?

#1004.OOP	From: Steve Teixeira <steixeir@borland.com>

John Lam <jlam@alchemy.chem.utoronto.ca> wrote:

>

> Does DELPHI support OLE Automation as a client?  In other words,

> can I program control the WordBasic object from within a DELPHI app?

>

> While on the topic of OLE, does anyone know whether future versions

> of DELPHI will encapuslate OLE 2.0 server code in the VCL, like

> MFC2.5 does?

>

> Thanks- the marketing hype isn't detailed enough :-)

>

> John Lam

>

John,

There are no built-in objects that facilitate OLE automation, but the OLE 2

API is at your disposal, should you wish to code at the API level.

In this release, the only built-in OLE component Delphi contains is for

only containers.

        -Steve Teixeira

         steixeir@borland.com

From: Steve Teixeira <steixeir@borland.com>

[snip]

..make that OLE containters.  :)

        -steve

From: walquic@il.us.swissbank.com (Chris Walquist)

Dear Steve,

I'm not clear on the distinction between "OLE 2" and "OLE automation".

How much of the following code will port to Delphi, and how does the

Delphi OLE container compare to VB's OLE object?  Our app uses VB's OLE

object, plus an object variable set with GetObject(), to communicate with

Excel:

Global XlApp as Object

..

Set XlApp = GetObject(,"Excel.Application")

XlApp.workbooks.open WorkBookPath,,,,XLPASSWD

XlApp.visible = True

..

Dim WorkBookPath$

Global Const WKBK_NAME = "MYPROJ.XLS"

Dim WkSheet$

WorkBookPath = "C:\CHRIS\MYPROJ.XLS"

WkSheet = "FA"

..

CurrForm!OleGraph.Class = "Excel.Chart.5"

CurrForm!OleGraph.OLETypeAllowed = OLE_EITHER

CurrForm!OleGraph.SourceDoc = WorkBookPath

CurrForm!OleGraph.SourceItem = WkSheet & "![" & WKBK_NAME & "]" & WkSheet

& " Chart 1"

Thanks much,

-chris walquist

My opinions are not always those of my employer.

Steve Teixeira <steixeir@borland.com> writes

> There are no built-in objects that facilitate OLE automation, but the

OLE 2

> API is at your disposal, should you wish to code at the API level.

>

> In this release, the only built-in OLE component Delphi contains is for

> OLE containers.

>

>       -Steve Teixeira

>        steixeir@borland.com

From: sraike@iconz.co.nz (William M. Raike)

In article <3k5r6u$5tu@tdelx01.tde.com>, The Green Meddler <kilgalen@tde.com>

says:

>

>Grant Carpenter wrote:

>>

>> >>Does DELPHI support OLE Automation as a client?  In other words,

>> >>can I program control the WordBasic object from within a DELPHI app?

>>

>> Unfortunately, I believe the answer is no.

>>

I've developed a Delphi component that lets you write an OLE Automation

controller easily, and am now exploring ways to market/sell it.  Anyone

wanting to express interest or wishing to make suggestions can reach

me at:

        sraike@iconz.co.nz

-- Bill Raike


Creating new instances

#1005.OOP	From: jnhodges@nps.navy.mil (John N. Hodges)

In article B0G@eclipse.sheridanc.on.ca, joe@hubble.sheridanc.on.ca (Joe Sant)

writes:

>

>Hi,

>Is it true that once your define a 'class' in Delphi you

>must explicitly call a 'create' function to create instances

>of the class ( My apologies for using C++ terminology ).  In

>C++ once a class is defined you can use the class to define

>local or global variables and they are automatically instantiated.

>That is a nice feature.  Am I wrong about Delphi?

>

No, you are right.  All constructors and destructors must be called

explicitly.

---

*   LT Nick Hodges, USN                     Naval Postgraduate School

*

*   jnhodges@nps.navy.mil                Information Technology Management

*

*   CIS: 71563,2250 AOL: NHodges                   Monterey, CA

*

*   "A man's gotta know his limitations...." - Clint Eastwood

*

*   Visit my homepage:  http://vislab-www.nps.navy.mil/~jnhodges

*

From: moscow@aed.org (Moscow)

Subject: Re: delphi:creating new instances

Date: 15 Mar 1995 05:24:01 GMT

John N. Hodges (jnhodges@nps.navy.mil) wrote:

: In article B0G@eclipse.sheridanc.on.ca, joe@hubble.sheridanc.on.ca (Joe

Sant) writes:

: >

: >Hi,

: >Is it true that once your define a 'class' in Delphi you

: >must explicitly call a 'create' function to create instances

: >of the class ( My apologies for using C++ terminology ).  In

: >C++ once a class is defined you can use the class to define

: >local or global variables and they are automatically instantiated.

: >That is a nice feature.  Am I wrong about Delphi?

: >

:

: No, you are right.  All constructors and destructors must be called

explicitly.

But in Delphi you cannot define variable of this class, only pointer

to the class, so it needs to be dynamically instantiated.

Gor Nishanov (gorik@cs.msu.su)

Subject: Re: delphi:creating new instances

From: The Green Meddler <kilgalen@tde.com>

Date: 15 Mar 1995 05:03:17 GMT

joe@hubble.sheridanc.on.ca (Joe Sant) wrote:

>

>

> Hi,

> Is it true that once your define a 'class' in Delphi you

> must explicitly call a 'create' function to create instances

> of the class ( My apologies for using C++ terminology ).  In

> C++ once a class is defined you can use the class to define

> local or global variables and they are automatically instantiated.

> That is a nice feature.  Am I wrong about Delphi?

>

> Thanks, Joe

>

> --

> Joe Sant                                  "Perfect nobility does not

> joe.sant@sheridanc.on.ca                   need a title; perfect wealth

> Phone: 1-905-845-9430 ext. 2512            does not need possessions"

> Computer Studies Sheridan College, ON, CA      The Huainanzi

i'm not sure i understand what you mean, but here's a go:

delphi classes simply tell the compiler how to build the assemly

code to make them run on the pc. the Create call is done when

you want to actually make one in memory to use.

FooClass = class(Tobject)

  procedure Bar;

end

var

Myfoo : FooClass;

begin

  Myfoo := FooClass.Create;

  Myfoo.bar;

end.

hope that helps.

GM


Creating controls on TTabbedNotebook

#1006.OOP	From: koterski@genghis (Steve Koterski)

Mike Frisch (mfrisch@bonk.io.org) wrote:

:       I am trying to create controls on a TTabbedNotebook in code

: only.  I am having a problem with the parent/child relationships and how

: the TTabbedNotebook interacts with the child controls.  I have created

: the TTabbedNotebook and some pages in code, but any attempts at creating

: controls on it have been unsuccessful.  I simply do not know how to bind

: a control to a TTabbedNotebook page.  Does anybody have any ideas?  All

: Delphi documention I've seen does not answer this question.

You need to make the parent of the object to be created the page on the

TabbedNotebook, not the TabbedNotebook itself. This is done like:

   Obj.Parent := TWinControl(NB.Pages.Objects[n]);

Where:

   Obj is the object to be created.

   NB is the name of the TabbedNotebook.

   Pages is used as it appears.

   Objects is used as it appears.

   n is the index number for the target page (starting at zero).

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

From: walsha@iccgcc.cle.ab.com

In article <3k8653$cpa@ionews.io.org>, mfrisch@bonk.io.org (Mike Frisch)

writes:

> I simply do not know how to bind

> a control to a TTabbedNotebook page.  Does anybody have any ideas?  All

> Delphi documention I've seen does not answer this question.

yeah, I found this poorly documented too.

search for TNotebook in help

then click on Using the Notebook Component.

then Adding Notebook Pages.

basically you add how many pages you intend to use, and then

go to the Object Browser and the first property of your TNotebook

object is ActivePage.

When you change the ActivePage, the notebook component on your form will

change contexts so you can add components. I didn't see this last

part written down or in help.

   andy

        walsha@cle.ab.com

From: mfrisch@r-node.io.org (Mike Frisch)

walsha@iccgcc.cle.ab.com wrote:

: basically you add how many pages you intend to use, and then

: go to the Object Browser and the first property of your TNotebook

: object is ActivePage.

: When you change the ActivePage, the notebook component on your form will

: change contexts so you can add components. I didn't see this last

: part written down or in help.

        This sounds great, but it doesn't work.  This is exactly what I

was doing.  See a later post from Borland (in this newsgroup) on how to

properly do it.  The method shown is _definitely_ not documented anywhere

in the Delphi manuals/on-line help.

Mike.

--

--------------------------------------------------------------------

  Mike Frisch                             Internet: mfrisch@io.org

  Northstar Technologies                    Compuserve: 76620,2534

  Newmarket, Ontario, Canada

--------------------------------------------------------------------


ActiveMDIChild and ChildWin

#1007.OOP	From: Steve Teixeira <steixeir@borland.com>

dtessman@gpu.srv.ualberta.ca (Dean Tessman) wrote:

>

> I'm kind of new to all this pascal stuff, as I have been an ObjectView

> programmer for the last year-and-a-half.

>

> I have run into a stumbling block in developing an MDI text editor (just to

> get used to Delphi stuff).

>

> I want to get the active child window, using ActiveMDIChild.  Then, I want

to

> call a function on this window.  I've tried using something along the lines

> of:

>

> var

>   ChildWin: TMDIChild;

> begin

>   ChildWin:=ActiveMDIChild;

>   ChildWin.AlignText('left');

> end;

>

> I run into problems here because TMDIChild and ActiveMDIChild causes a type

> mismatch.  If I use TForm instead of TMDIChild, ActiveMDIChild messes up.

>

ActiveMDIChild is of type TObject, whereas your ChildWin is of type TMDIChild,

so

that's why you're getting a type mismatch.  Try this:

var

  ChildWin: TMDIChild;

begin

  ChildWin:=ActiveMDIChild as TMDIChild;

  ChildWin.AlignText('left');

end;

        -Steve Teixeira

         steixeir@borland.com


Why call Destructor??

#1008.OOP	From: dlam@zeta.org.au (David Lam)

I am new to delphi and there is one thing that really bugs me.

I am comparing it with C++.

If I declare an object in Delphi, I have to explicitly called the

Create method before I can use it. For example,

        var

                Employee: TEmployee;

        begin

                Employee.Create;

        :

        :

What's worse, I have to explicitly called the Destructor(Free or Destroy).

This is like declaring a pointer to an object, alloc memory using new

and delete the object in C++. But in C++ I can have an automatic variable

that is created on the stack and get destroy automatically when the

function exit.

Is there a equivalent of this in ObjectPascal, or what's the reason behind

this?

Thanks in advance.

David Lam

From: kimk@rmii.com (Bryan Slatner)

In article <3k893k$fpa@godzilla.zeta.org.au> dlam@zeta.org.au (David Lam)

writes:

>I am new to delphi and there is one thing that really bugs me.

>I am comparing it with C++.

>If I declare an object in Delphi, I have to explicitly called the

>Create method before I can use it. For example,

<stuff deleted>

>What's worse, I have to explicitly called the Destructor(Free or Destroy).

>This is like declaring a pointer to an object, alloc memory using new

>and delete the object in C++. But in C++ I can have an automatic variable

>that is created on the stack and get destroy automatically when the

>function exit.

David -

In C++, if you have some class XClass and declare a variable of type XClass,

then that object's default constructor will be called upon entrace to the

function where it is declared (or at program startup, if it's a global) and

will be automatically destroyed upon the function's exit (or at program end,

if it's a global).

If, however, you declare some variable of type *XClass, it is *not*

auotmatically contructed and it is *not* automatically destroyed--you must

explicitly create and destroy the instance with the "new" and "delete"

operators.

The latter example is like how it works Delphi.  *All* object instances

in Delphi are dynamic and, hence, must be explicitly created and destroyed.

I hope this helps,

+----------------------------------------------------------------+

| Bryan Slatner, Software Engineer | "His honor, rooted in       |

| and all around nifty guy.        |  dishonor stood, and his    |

|                                  |  faith, unfaithful, kept    |

| kimk@rmii.com                    |  him falsely true."         |

| 71175.3534@compuserve.com        |   -Sir Alfred Lord Tennyson |

|----------------------------------------------------------------|

| The opinions expressed herein are not necessarily the opinions |

| of TurboPower Software Company.  If they were, I would own it, |

| which I don't, so they aren't...necessarily, that is.          |

+----------------------------------------------------------------+

From: dmurdoch@mast.queensu.ca (Duncan Murdoch)

In article <3k893k$fpa@godzilla.zeta.org.au> dlam@zeta.org.au (David Lam)

writes:

>What's worse, I have to explicitly called the Destructor(Free or Destroy).

>This is like declaring a pointer to an object, alloc memory using new

>and delete the object in C++. But in C++ I can have an automatic variable

>that is created on the stack and get destroy automatically when the

>function exit.

>Is there a equivalent of this in ObjectPascal, or what's the reason behind

>this?

There's a general principle in Pascal that until you assign something to a

variable, its value is undefined.  Requiring constructors follows naturally

from this principle.

There's a general good practice in programming that if you allocate something,

you should take responsibility for disposing of it.  Requiring destructors

follows naturally from this, and from the fact that it's you who must have

called the constructor.

Delphi violates the first rule a little bit, in that the environment sometimes

creates and assigns variables for you, but it also follows the second rule in

these cases, and takes responsibility for cleanup.  It's only in cases where

you decide to create the variable yourself that you're responsible for cleanup

as well.

Duncan Murdoch


Exception handling?

#1009.OOP	From: dmurdoch@mast.queensu.ca (Duncan Murdoch)

In article <3kejuu$qg0@pipe3.pipeline.com> mwj@pipeline.com (Jin Mai) writes:

>

>VB don't have good exception handlng. To make sure

>VB app don't crash, vb programmers have to put an

>error in every subroutine and event. How is Delphi

>handle exception error?

Exception handling is built into the language.  There are

two new constructs to handle it:  "try ... finally..."  and "try ... except

...".  The first of these lets you specify code that will be guaranteed to

execute, even if any exception has occurred.  You use this to clean up; you

don't get resource leaks if you use that.  The second construct allows you to

take action on specific exceptions.

You can define your own exceptions and raise them in your own code.

While debugging, you can tell the IDE to break your code whenever an exception

occurs, so you see the exact place where there's a problem.

This is a very nice feature of the language.

Duncan Murdoch

From: genenet@ix.netcom.com (blank)

In <3kejuu$qg0@pipe3.pipeline.com> mwj@pipeline.com (Jin Mai) writes:

>

>

>VB don't have good exception handlng. To make sure

>VB app don't crash, vb programmers have to put an

>error in every subroutine and event. How is Delphi

>handle exception error?

>

>--

>Jin Mai        mwj@pipeline.com

>

There is an exception object to inherit/derive from.  They

seem (I haven't played much yet) to do a good job of classifying

errors ( EDivByZero, EOverFlow, EInvalidPointer, etc).

Some constructs are:

try

  { do your regular code}

finally

  { if an error occured in regular code, handle it here}

end;

try

  result:=sum div 0;

except

  on EDivByZero do result :=0;

end;

Also you can reraise the except by using the keyword "raise".

Gene

From: isc@panix.com (David Koosis)

>In <3kejuu$qg0@pipe3.pipeline.com> mwj@pipeline.com (Jin Mai) writes:

>>

>>How is Delphi handle exception error?

>>

Exception handling is handled nicely.

It's lifted directly from C++.

Take a look at Stroustrup for an explanation.

//dk

--

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 ISC Consultants, Inc.                            14 East 4 Street Ste 602

                                                  New York City  10012-1141

 "Technical Consulting & Training Since 1973"     212 477-8800 fax:477-9895


Object Dereferencing Problem

#1010.OOP	From: dmurdoch@mast.queensu.ca (Duncan Murdoch)

In article <3klj64$mrn@news-2.csn.net> r_ison@csn.net (Roger E. Ison) writes:

>I want to make objects (of a type derived from TObject)

>containing pointers (links) to other objects of the same type.

>Something like this:

>type thing = class(TObject)

>        link: thing

>     end;

>This is inspired by the fact that Delphi objects are all

>in the heap, and the reference model automagically

>dereferences the pointer for you; so that if  z  is an

>object,  z.fieldname  really means   z^.fieldname

>However, to create linked lists you need to be able to

>actually assign the link a value which is an address

>without dereferencing, and there doesn't seem to be any

>way to do this.

I don't see the problem.  What's wrong with the method below?

var

  thing1, thing2 : thing;

begin

  { create them ... etc. }

  thing1.link := thing2;

end.

Duncan Murdoch

From: dmurdoch@mast.queensu.ca (Duncan Murdoch)

In article <3knlko$2gn@peaches.cs.utexas.edu> turpin@cs.utexas.edu (Russell

Turpin) writes:

>In article <dmurdoch.1687.2F6ED4A8@mast.queensu.ca>,

>Duncan Murdoch <dmurdoch@mast.queensu.ca> wrote:

>> var

>>   thing1, thing2 : thing;

>> begin

>>  { create them ... etc. }

>>  thing1.link := thing2;

>Is thing1 := thing2 also pointer assignment?  More generally,

>how does one make a copy constructor?

Yes, thing1 := thing2 is just a pointer assignment.  I don't think there's any

built-in way to do a copy constructor; you would have to write your own (but I

could be wrong!).  There is a built-in way to find the size and class of an

instance, so it wouldn't be hard to write a shallow copy, but a deep copy

requires knowledge about what the fields represent.

Duncan Murdoch

From: turpin@cs.utexas.edu (Russell Turpin)

-*-----

In article <dmurdoch.1691.2F7024D4@mast.queensu.ca>,

Duncan Murdoch <dmurdoch@mast.queensu.ca> wrote:

> .... a deep copy requires knowledge about what the fields represent.

And of how they are used.  But, then, it always does.  There

are no obvious, clean semantics for a universal deep copy.

Russell

--

"Why does our innate subjective spacing of qualities accord so well with the

functionally relevant groupings in nature as to make our inductions come out

right? ...  Creatures inveterately wrong in their inductions have a pathetic

but praiseworthy tendency to die before reproducing."   --  W. V. O. Quine

From: Steve Teixeira <steixeir@borland.com>

Subject: Re: Delphi: obj deref problem  (OR: copy constructors)

Date: 23 Mar 1995 18:00:50 GMT

dmurdoch@mast.queensu.ca (Duncan Murdoch) wrote:

>

> In article <3knlko$2gn@peaches.cs.utexas.edu> turpin@cs.utexas.edu (Russell

Turpin) writes:

> >In article <dmurdoch.1687.2F6ED4A8@mast.queensu.ca>,

> >Duncan Murdoch <dmurdoch@mast.queensu.ca> wrote:

> >> var

> >>   thing1, thing2 : thing;

> >> begin

> >>  { create them ... etc. }

> >>  thing1.link := thing2;

>

> >Is thing1 := thing2 also pointer assignment?  More generally,

> >how does one make a copy constructor?

>

> Yes, thing1 := thing2 is just a pointer assignment.  I don't think there's

any

> built-in way to do a copy constructor; you would have to write your own (but

I

> could be wrong!).  There is a built-in way to find the size and class of an

> instance, so it wouldn't be hard to write a shallow copy, but a deep copy

> requires knowledge about what the fields represent.

>

> Duncan Murdoch

Use the Assign() method to copy instances.

        -Steve Teixeira

         steixeir@borland.com


Constructor Question

#1011.OOP	From: bcwright@ucsd.edu (Brian C. Wright)

In article <200327003wnr@landscap.demon.co.uk>, Marc@landscap.demon.co.uk

(Marc Palmer) says:

>In C++ you use overloaded

>constructors to pass variables to objects as you create them. AFAIK

>this is not the case in Delphi, as you are restricted to one

>constructor - Create.

Marc,

I don't believe that you are restricted to one constructor.  You just

can't overload the constructor name.  For instance, a Delphi class in

an application I am currently working on has two constructors:

Class TGrowRec

  Constructor CreateFromBuffer(aGrowRecBuff: RGrowRec);

  Constructor CreateFromFile(var aFile: Text);

  ...

  end;

I call one constructor (CreateFromFile) when the application initializes

and the records are read from file, and the other constructor is called

when the user creates a record at run time through a dialog box.

brian.


Objects and classes

#1012.OOP	From: Steve Teixeira <steixeir@borland.com>

kvlahos@lbs.lon.ac.uk (Kiriakos Vlahos) wrote:

>

> A few basic questions about the old and the new object model.

>

> a) Is it safe to mix the two in the same program?

Yes.  Just follow the directions outlined in the README.TXT for a few basic

dos/don'ts.

> b) Should we consider the old object model as obsolete and scheduled to be

>     phased out?  For instance, in new code should we stop using TCollections

>     etc. that we grew to love and replace them with TStrings etc.?

The new classes give EH, RTTI, and are OLE2-compatible, whereas 'OBJECT's do

not

and are not.  Also note that Delphi's CLASSes don't use any DSeg space for the

VMT as do their OBJECT cousins.  You should probably move to classes for your

Delphi

work, but anything you need to share with the DOS world (ie, BP7), keep as an

object for now.

Thanks for your other suggestions re more OOPish behavior!

        -Steve Teixeira

         steixeir@borland.com


Constructor calling

#1013.OOP	From: Steve Teixeira <steixeir@borland.com>

gustavo.exel@mandic.ax.apc.org (Gustavo Exel) wrote:

>

> Hi,

>

> Would someone know why this:

>

> type

>     TMyClass = class

>         constructor Create;

>         ...

>     end;

> var

>     V : TMyClass;

> begin

>     V.Create;

>

> generates GPFs when I subsequently use V, while calling new like in:

>

>     V := TMyClass.Create;

>

> works correctly?

>

> What's the difference between these two ways of constructing a class

> instance?

>

>

> I'm working with Delphi, but I think similar problems also happen with

> BP7+OWL (although not with BP7 compilng to real or protected mode DOS).

>

The second instance is the correct way to create a class instance in Delphi.

The reason the first doesn't work is because you can't call a method (even the

constructor) of V until the instance V is created (Catch-22) -- hence, the

"instance := type.create" syntax.

        -Steve Teixeira

         steixeir@borland.com


Overriding Create?

#1014.OOP	From: dmurdoch@mast.queensu.ca (Duncan Murdoch)

In article <3l2d7f$jb0@linda.teleport.com> ediss@teleport.com writes:

>Thanks for your response.  I removed 'override' and it compiles OK.  BUT, I

>don't get it!  I want to extend a virtual method.

Sorry, I didn't realize you were writing a component.

There are two conflicting desires here:

1.  You want to create a constructor that takes different parameters from the

default one.

2.  You want to create a component that the IDE can drop onto a form.

The problem is that the IDE will always call the constructor with the standard

parameters.  If you want to change the behaviour when it does that, then you

should use the standard parameters and override.  If you want another way to

create your component, then create a different constructor.  I'd suggest not

calling it Create; that's just going to cause confusion.

What "inherited" means is to call the method with the same name from the

parent type.  You can use "inherited Create(...)" whether you use override or

not.

All of this should be taken with a grain of salt; I know a lot about how BP 7

objects work, but Delphi classes are new to me too.

Duncan Murdoch

From: ediss@teleport.com

On Sat, 25 Mar 1995, Duncan Murdoch wrote:

> >the correct way to create a control class that accepts data on creation?

>

> Just the way you did it, but without "override".  You'll create a new

> constructor that takes different parameters than the old one.  You'd use

> "override" if it was a virtual constructor that could be called by something

Thanks for your response.  I removed 'override' and it compiles OK.  BUT, I

don't get it!  I want to extend a virtual method.  In the new constructor

Create, I call 'inherited Create' and that passes muster.  If the new

Create is replacing the old rather than extending it why does it work?

Also, here's an excerpt from the online CWG:

" When declaring new component types, always add the

  override directive if your new component declares a

  Create method. The Create method of TComponent is

  virtual, so to ensure that Delphi calls the correct

  constructor when a user drops your component on a

  form, you must override the Create method.

  Note: When you override the Create constructor in

  a descendant object type, you should call the inherited

  Create to complete the initialization of inherited fields

  and properties. Always use the inherited keyword when ..."

Sign me Puzzled and Perplexed in Pascalland, Scott

--


Multiple Inheritance In Delphi

#1015.OOP	From: edgrant@ix.netcom.com (Ed Grant)

In <3l03lk$27u@news.onramp.net> grego@onramp.net writes:

>

>       Does anyone know how you would go about inheriting multiple

>ancestor classes into a new custom class in delphi? In C++ you can do

>something like:

>       class MyClass : public Class1, public Class2, private Class 3 {

>               [ other stuff....]

>       };

>

>       This lets you combine several classes together into a new class

in

>a single stroke, without having to "stack" classes one inside the

other. As

>far as I can tell, the inability to do this is the _only_ drawback to

Delphi.

>( That and lack of support for alternate OSs ).

>

>       Thanks,

>               Snow Crash

>

>

 Delphi doesn't do multiple inheritance.  To some people that's bad news

to others good news.

From: chasb@strat.osf.org (Charles Bennett)

> Does anyone know how you would go about inheriting multiple

> ancestor classes into a new custom class in delphi?

With single inheritance it's often better to do "mixins" by

aggregation - the new class has instance variables of the

classes that you would have otherwise inherited from.

The new class reimplements the public interface of the

mixin classes by using delegation:

{pardon the pidgin pascal}

type A = class(Object)

begin

 public:

        procedure foo( a: integer );

 private:

        x: integer;

end;

type B = class(Object)

begin

 public:

        procedure baz( a: real );

 private:

        y: integer;

end;

type MixedIn = class(Object)

begin

 public:

        procedure foo( a: integer );

        procedure baz( a: real );

 private:

        myA : A;

        myB : B;

        z       : integer;

end;

{now the delegation stuff}

procedure MixedIn.Create

begin

        myA = A.Create;

        myB = B.Create;

end;

procedure MixedIn.foo( a: integer )

begin

        myA.foo( a );

end;

{ Yes, it's cumbersome, but is that enough to give the flavor? }

chasb

------------------------------------------------------------------------------

-

Chas. Bennett           OSF Research Institute

chasb@osf.org           Trust Project Configuration Management

x8860

                                        http://world.std.com/~chasb

OOPS Page:                      http://world.std.com/~chasb/ot.html

------------------------------------------------------------------------------

-

--

------------------------------------------------------------------------------

-

Chas. Bennett           OSF Research Institute

chasb@osf.org           Trust Project Configuration Management

x8860

                                        http://world.std.com/~chasb

------------------------------------------------------------------------------

-


Missing multiple inheritance ... what instead?

#1016.OOP	From: dmurdoch@mast.queensu.ca (Duncan Murdoch)

In article <3l40pe$kcj@peaches.cs.utexas.edu> turpin@cs.utexas.edu (Russell

Turpin) writes:

>Pointing out delegation as a workaround for lack of MI is

>somewhat foolish, because it can equally well be pointed

>out as a replacement for single inheritance!  Rather than

>deriving class B from class A, when you think you ought

>to do so, always make a field of type A in B and create B

>methods that delegate to A methods.

>What?  You think this is terribly awkward?  You would

>rather just inherit in those cases where B should assume

>A's methods and behavior?

The point is that both delegation and multiple inheritance have their

drawbacks; you have to consider the tradeoff.  You pointed out the drawbacks

to delegation pretty well; the only thing I'd contest is that your descendant

type can't descend from either f or g, and only need to delegate one.  There

are hardly any cases of perfect symmetry in real life, and usually your

descendant is closer to a special case of one or the other "parent".

The drawbacks of multiple inheritance are the ambiguities it introduces or the

global consequences of trying to work around the ambiguities.  For example, if

both f and g have a method called "M", and my new class h is descended from f

and g, then what does h.M mean?  If both f and g descend from e, and extend

M in different ways, then which override of e.M should apply?  What if the

user is treating the h object as an instance of e?

You can either forbid these situations from ever occuring (i.e. incur global

consequences of every naming choice as you design e and f and g), or come up

with rules for disambiguation which the programmer has to learn.  The

designers of Delphi decided to do neither of these; they avoid the problem.  I

think it keeps programs simpler and easier to understand, and that's almost

always a good idea.

Duncan Murdoch

From: curzon@io.org (Richard Curzon)

In article <60-60-0-0-f7336321@beard.nest.nl>,

Berend de Boer <berend@beard.nest.nl> wrote:

>

>Maybe there are situations in which multiple inheritance would be handy

>(have not come accross this as long as I program in OOP, which is about

>4 years and I've done lots of OOP coding on many different levels), but

>I think the resulting mess is better to be avoided.

>

>Groetjes,

>

>Berend (-:

I agree with Berend.  Experience has taught me the same thing, that

encapsulation is more useful and usable than inheritance, especially

*during* development.

If you've found something *really* reusable over several projects, go back

and build some class hierarchies... if you're sure it's worth it.

A good exposition of "prefer composition to inheritance" is in the Gang

of Four Book (Design Patterns: Elements of Reusable Object Oriented

Software).

Richard Curzon // curzon@io.org // 71371.2521@compuserve.com

"Productivity varies inversely with the number of ways you can screw up!"

--

Richard Curzon // curzon@io.org // 71371.2521@compuserve.com

"Productivity varies inversely with the number of ways you can screw up!"

From: turpin@cs.utexas.edu (Russell Turpin)

-*-----

In article <3l502u$1ae@ionews.io.org>, Richard Curzon <curzon@io.org> wrote:

> ...  Experience has taught me the same thing, that

> encapsulation is more useful and usable than inheritance,

> especially *during* development.

True, but this comment is almost entirely tangential to

the issue of multiple inheritance.  As long as you

believe in inheritance AT ALL, as long as you believe

that there is *ever* a case when it is useful to have

C inherit from A, then the question of multiple

inheritance comes up as soon as you have a B that is

also reasonable an ancestor to B.

> A good exposition of "prefer composition to inheritance"

> is in the Gang of Four Book (Design Patterns: Elements

> of Reusable Object Oriented Software).

I thought that some of the patterns in that book made

use of MI.

Russell

--

"Why does our innate subjective spacing of qualities accord so well with the

functionally relevant groupings in nature as to make our inductions come out

right? ...  Creatures inveterately wrong in their inductions have a pathetic

but praiseworthy tendency to die before reproducing."   --  W. V. O. Quine

From: turpin@cs.utexas.edu (Russell Turpin)

-*------

In article <60-60-0-0-f7336321@beard.nest.nl>,

Berend de Boer <berend@beard.nest.nl> wrote:

> You created a MixedObject with two fields, one being the

> sorted tree, the other the blinkObject (whatever that is).

This is delegation.  It requires doing something that is

quite burdensome and unnatural under the circumstances,

to wit, for each method f of SortedTreeNode and each method

g of blinkObject, one must now create methods f and g of

MixedObject that invoke the corresponding methods for the

two delegated types.  If one adds a new method to

SortedTreeNode, it requires changing *every* class that is

a (contains a) SortedTreeNode.  Blech!

Pointing out delegation as a workaround for lack of MI is

somewhat foolish, because it can equally well be pointed

out as a replacement for single inheritance!  Rather than

deriving class B from class A, when you think you ought

to do so, always make a field of type A in B and create B

methods that delegate to A methods.

What?  You think this is terribly awkward?  You would

rather just inherit in those cases where B should assume

A's methods and behavior?

Exactly.

Russell

--

"Why does our innate subjective spacing of qualities accord so well with the

functionally relevant groupings in nature as to make our inductions come out

right? ...  Creatures inveterately wrong in their inductions have a pathetic

but praiseworthy tendency to die before reproducing."   --  W. V. O. Quine


Detecting previous Instance

#1017.OOP	From: moscow@aed.org (Moscow)

Gary L. McMillan (mcmillan@eskimo.com) wrote:

:       How do I detect a previous instance of an application

: running? I'm wanting to avoid a second instance of my app

: running.

You have hInstance and hPrevInst variables, which are

defined in SYSTEM unit. Check hPrevInst

Gorik

(gorik@cs.msu.su Gor V.Nishanov)

From: uk.twyford.rnelson@wpo.borland.com (Roy Nelson)

In article <D62t9E.4qF@eskimo.com> mcmillan@eskimo.com (Gary L. McMillan)

writes:

>From: mcmillan@eskimo.com (Gary L. McMillan)

>Subject: Delphi: Detecting previous Instance

>Date: Mon, 27 Mar 1995 01:53:38 GMT

>        How do I detect a previous instance of an application

>running? I'm wanting to avoid a second instance of my app

>running.

Hope this code helps. The Second app exits after showing a message box.

procedure TForm1.FormCreate(Sender: TObject);

begin

   if hPrevinst <> 0 then

      begin

      ShowMessage('A previous instance was running I am getting out');

      PostQuitmessage(0);

      end;

end;

--------------------------------------

-- Roy Nelson

-- Borland European Escalation Center

--------------------------------------

From: Steve Teixeira <steixeir@borland.com>

Subject: Re: Delphi: Detecting previous Instance

Date: 27 Mar 1995 19:46:56 GMT

uk.twyford.rnelson@wpo.borland.com (Roy Nelson) wrote:

>

> In article <D62t9E.4qF@eskimo.com> mcmillan@eskimo.com (Gary L. McMillan)

writes:

> >From: mcmillan@eskimo.com (Gary L. McMillan)

> >Subject: Delphi: Detecting previous Instance

> >Date: Mon, 27 Mar 1995 01:53:38 GMT

>

> >        How do I detect a previous instance of an application

> >running? I'm wanting to avoid a second instance of my app

> >running.

>

> Hope this code helps. The Second app exits after showing a message box.

>

> procedure TForm1.FormCreate(Sender: TObject);

> begin

>    if hPrevinst <> 0 then

>       begin

>       ShowMessage('A previous instance was running I am getting out');

>       PostQuitmessage(0);

>       end;

> end;

>

If you want to be "Delphi-esque" <G>, you should call Application.Terminate,

which does a PostQuitMessage(0) for you.

        -Steve Teixeira

         steixeir@borland.com

From: Steve Teixeira <steixeir@borland.com>

[snip]

Why go through all the trouble when you can just check to see if hPrevInst

is equal to zero?

        -Steve Teixeira

         steixeir@borland.com


Free method causes GPF?

#1018.OOP	From: Steve Teixeira <steixeir@borland.com>

freimuth@trilogy.com (Rolf Freimuth) wrote:

>

> According to the manuals, the free method should not cause a GPF even

> when used on a variable that has already been freed or has not been

> created..

>

> When I do the following:

>

> procedure TForm1.Button1Click(Sender: TObject);

> var

>       sList: TStrings;

> begin

>       sList.Free;

> end;

>

> .... I get a GPF.  What am I doing wrong?

>

The docs say that freeing a *Nil* pointer won't result in an error.  Sine

you are declaring sList on the stack, it will have an initial value of

whatever

happened to be on the stack at the time.  If you move sList inside a class

declaration (classes automatically 0-out all their data members), then Free

will work as you expect. Or you can set sList to Nil yourself before

calling Free.

        -Steve Teixeira

         steixeir@borland.com


SetWindowsPos....

#1019.OOP	From: keeper@netcom.com (Mark R. Johnson)

In article <D64puF.12B@eskimo.com>,

   mcmillan@eskimo.com (Gary L. McMillan) wrote:

[...]

>    SetWindowPos(hPrevinst,HWND_TOP,0,0,0,0,64);   {Here!}

[...]

>Why does the SetWindowPos call not make the previous instance

>the topmost window

The first argument to SetWindowPos() is suppose to be a window handle

(HWND), not an instance handle (HINSTANCE).  They're not the same.

--Mark Johnson

______________________________________________________________________________

Mark R. Johnson     _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

Atlanta, GA USA    _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

keeper@netcom.com _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

From: Steve Teixeira <steixeir@borland.com>

mcmillan@eskimo.com (Gary L. McMillan) wrote:

>

>

> procedure TForm1.FormCreate(Sender: TObject);

> begin

>       If hPrevinst <> 0 then

>       begin

>     ShowMessage('Proglock Is Already Running');

>     SetWindowPos(hPrevinst,HWND_TOP,0,0,0,0,64);   {Here!}

>     Application.Terminate;

>       end;

>       ProgIni := TIniFile.Create('progman.ini');

>   ProgEditLevel := ProgIni.ReadInteger('Restrictions',

> 'EditLevel', 0);

>

> Why does the SetWindowPos call not make the previous instance

> the topmost window

>

Because hPrevInst is an instance handle, not a window handle.

        -Steve Teixeira

         steixeir@borland.com


Class Allocation

#1020.OOP	From: Steve Teixeira <steixeir@borland.com>

sean.palmer@delta.com (Sean Palmer) wrote:

>

> ST>The new classes give EH, RTTI, and are OLE2-compatible, whereas 'OBJECT

> ST>not

> ST>and are not.  Also note that Delphi's CLASSes don't use any DSeg space

> ST>VMT as do their OBJECT cousins.  You should probably move to classes fo

> ST>Delphi

> ST>work, but anything you need to share with the DOS world (ie, BP7), keep

> ST>object for now.

>

> ST>Thanks for your other suggestions re more OOPish behavior!

>

> ST> -Steve Teixeira

> ST>  steixeir@borland.com

>

> Steve, is there any way to 'fool' a class into pointing somewhere you have

> already allocated (i.e. on the stack, in an array, or whatever)? I want to

> be able to avoid heap allocation overhead in some situations.

>

> i.e. would this work?

>

> var

>   myClass:tSomeClass;

>   stackInstance:array[0..sizeof(tSomeClass)-1] of byte;

> begin

>   pointer(myClass):=@stackInstance; {point to stack}

>   myClass.init;  {bypass create}

>   myClass.doSomething;

>   myClass.done;  {bypass destroy}

>   end;

>

> Even though this still uses a pointer to access the object, at least it

> doesn't have to allocate space on the heap. This could come in handy if I

> wanted to make my own special classes for some reason that needed to be

> created quickly.  I wouldn't want to use this method on any other kind of

> Class, I think.

>

> What is your estimate on overhead of the RTL's .Create methods and New

> function?

>

This is actually a hairy problem.  The primary reason why I don't see this

working is because the Virtual Method Table and Dynamic Method Table do not

get set up until you call the constructor.  At best, I can see you copying

an _existing_ instance somewhere in memory, and using that, but that seems

dubious (and doesn't appear very useful anyway).

BTW, another gotcha.. SizeOf(TSomeClass) is won't compile (even if it did,

it would only be 4 bytes <g>), but you can use MyClassInstance.InstanceSize,

which

returns a word-sized value.

Take care,

        -Steve Teixeira

         steixeir@borland.com


OOP - Pointers and Components
Pointers and Components

#1021.OOP	From: Jerry Black <black@xmission.com>

dmurdoch@mast.queensu.ca (Duncan Murdoch) wrote:

>

> In article <3ldnjv$9vn@news.xmission.com> Jerry Black <black@xmission.com>

writes:

>

> >TYPE

> >        MYDATA = ^STRING;

>

> >VAR

> >        data : MYDATA;

>

> >Form1.TEdit1_Exit(Sender:TObject)

> >begin

> >        data^ := TEdit1.Text;

> >end;

>

> This has the same problem as the original:  you never allocated data^.  You

> need

>

>   data := NewStr(TEdit1.Text);

>

> The NewStr function allocates space for the string on the heap, and returns

a

> pointer to it.  One warning:  In BP, NewStr returns Nil if the string is

> empty.  This means that something like Writeln(data^) will write garbage, or

> cause a GPF.   I don't know if Delphi fixes this, but if not, you should

write

> a little wrapper routine that checks for Nil, so something

> like StringFromHeap(data) will always return a valid string.

>

> It's also possible to use just

>

>   New(Data);

>   Data^ := TEdit1.Text;

>

> but this version wastes heap space.  It always allocates 256 bytes,

regardless

> of the length of the string.  NewStr just allocates the minimal amount of

> space.

>

> If you use NewStr, use DisposeStr to get rid of it; use Dispose with New.

>

> Duncan Murdoch

Thanks Duncan for the corrections.

Jerry Black.

From: awax@dep071.ennet.krasnoyarsk.su

In article <vdata.13.000FE7EE@inforamp.net>, vdata@inforamp.net (Bryan

Zarnett) writes:

>Im trying to place the data from a TEdit component into a string pointer.

>Someone say this is simple...

>

>basically I wrote

>

>var

> data: ^string;

>

>Form1.TEdit1_Exit(Sender:TObject)

>begin

>     data^:=TEdit1.Text;

>end;

>

>Got a GPF...any ideas how to do this right?

>The reasons Im playing with this is because Im trying to wrote a TDib class

to

>handle DIB images so I can try and create a WING component...good luck, I

>know..but

>

   Naturally ! You MUST have a GP or some other error in this situation.

Because Text is a

property, not a field of object. Therefore, it doesn't exist really, Delphi

simulate it

for you. You should write the following code instead of the above :

   S    := TEdit^.Text;

   Data := @S;

   AWAX.


How does one clone a component

#1022.OOP	From: turpin@cs.utexas.edu (Russell Turpin)

-*-----

In article <3jfjhf$mn1@nps.navy.mil>,

John N. Hodges <jnhodges@nps.navy.mil> wrote:

> Yeah, but he wanted to clone a component dynamically.  I hope

> that doesn't take ten minutes on my 486!

Yes.  It looks like one has to write a procedure -- for each

component that one wants to clone -- that copies each property

by name:

    Y.Font := X.Font;            {Copy properties}

    ...

    Y.OnClick := X.OnClick;      {Don't forget the event handlers}

    ...

I was hoping that there were some built-in primitives to help in

doing this generically, i.e., something like:

    for (i=0; i<X.NumProp; i++)  {Oops: this is C!}

    begin                        {Back to Pascal ...}

        Y.Property[i] := X.Property[i]

    end

What I *really* want is a copy constructor that is smart enough

to copy properties, but not private attributes that should not be

copied straight.  Ah, well.  It probably is not that important to

have a generic capability for this.

Russell

--

  "How can I be called conservative?  I'm pro-prostitution,

  pro-pornography, pro-abortion, pro-legalization of drugs,

  pro-homosexuality, and pro-drag queens." -- Camille Paglia


Calling C DLL from Delphi

#1000.C	From: dmurdoch@mast.queensu.ca (Duncan Murdoch)

In article <1995Mar20.215639.26351@il.us.swissbank.com> hendryj@mcs.com

writes:

>I need to call some functions from a C-based DLL. In the process, I also need

>to use data structures and macros which are defined in an accompanying C

>header file.

>Can it be done with Delphi? Can I call C macros from Pascal code?

There's no problem calling the functions in the DLL, except for ones with a

variable number of parameters.  (You can declare multiple functions to handle

those, if you want.)  Use the "cdecl" declaration in your import unit if the C

functions weren't compiled with the "pascal" calling convention.

There's nothing in Delphi that can make use of the header file.  You'll have

to rewrite it and include the declarations and equivalent versions of any

macros you need in Pascal.  Since Delphi doesn't support macros, you'll have

to change some of them to functions instead; if the macros were used on

multiple types of arguments, this might be a pain too.

Duncan Murdoch

From: jreynd@unm.edu (john t UNM.HOSPITAL reynold)

In article <1995Mar20.215639.26351@il.us.swissbank.com>,

 <hendryj@mcs.com> wrote:

>

>Folks,

>

>I need to call some functions from a C-based DLL. In the process, I also need

>to use data structures and macros which are defined in an accompanying C

>header file.

>

>Can it be done with Delphi? Can I call C macros from Pascal code?

>

It's funny you should ask.  I spent several hours trying to do the same

last night.  I wrote a DLL in VC++ that I've been calling from VB and

VC++.

It takes as argument a pointer to a structure of what VB and Pascal call

Integers, and VC++ calls Shorts.

I tried declaring it these ways:

Function MyFunc( Var MyVar  :  StructName) : Integer;

Function MyFunc( MyVar : ^StructName) : Integer;

Function MyFunc( Var MyVar : ^StructName) : Integer;

Function MyFunc( Var MyVar^ : Pointer) : Integer;

Function MyFunc( MyVar^ : Pointer) : Integer;

I tried calling it using @MyVar and Myvar.

The only thing that worked was the first declaration, but it netted me

GPFs.  The functions and procedures in the same DLL that don't take

arguments work just fine.  I believe that all of the above dec's are

wrong, because I'm not actually passing a pointer to the structure.  What

am I doing wrong?

John Reynolds

From: Steve Teixeira <steixeir@borland.com>

s8153119@spring.nchu.edu.tw () wrote:

>

> Steve Teixeira (steixeir@borland.com) wrote:

> : If your C/C++ functions use the Pascal calling convention like this:

>

> : void far pascal foo;

> Isn't there a "cdecl" in Delphi?

>

Yes, I did mention that later in my message.  However, many Windows DLLs

written

in C/C++ (The Windows API, for example) use the Pascal calling convention, so

it

is worth mentioning.

        -Steve Teixeira

         steixeir@borland.com


Visual Bascom [sic] - Equivalent of VB DoEvents
Equivalent of VB DoEvents

#1000.VB	From: The Green Meddler <kilgalen@tde.com>

pacsoft@netcom.com (Wilhelm Sarasalo) wrote:

>

> Got my copy of delphi a few days ago and I find it to be a lot better

> than all the positive press that I have been reading.

>

> However:

>

> How do you yield control to other tasks? "DoEvents" in VB or "Sleep" in

> ObjectPAL. I tried "WaitMessage", but that isn't it.

>

check out the OnIdle event for applications. apparently that's

where peekmessage and waitmessage are in delphi.

> How do you make more room to the speedbar. I don't seem to be able to move

> the component palette very far to the right. On a high resolution screen

> there is a lot of wasted real estate on the right, but I can't get all the

> buttons I want onto the speedbar.

>

have you treid grabbing the edge of the speedbar on the right

and dragging it right as far as possible? i put every speedbutton

i could find in my speedbar...(G)

> thanx,

> Wilhelm

>

GM

From: Tom Cabanski <sig@teleport.com>

> How do you yield control to other tasks? "DoEvents" in VB or "Sleep" in

> ObjectPAL. I tried "WaitMessage", but that isn't it.

It's the TApplication object's ProcessMessages event (typically invoked as:)

Application.ProcessMessages

From: pacsoft@netcom.com (Wilhelm Sarasalo)

The Green Meddler (kilgalen@tde.com) wrote:

: pacsoft@netcom.com (Wilhelm Sarasalo) wrote:

: >

: > Got my copy of delphi a few days ago and I find it to be a lot better

: > than all the positive press that I have been reading.

: >

: > However:

: >

: > How do you yield control to other tasks? "DoEvents" in VB or "Sleep" in

: > ObjectPAL. I tried "WaitMessage", but that isn't it.

: >

: check out the OnIdle event for applications. apparently that's

: where peekmessage and waitmessage are in delphi.

Thanx for pointing me to OnIdle. What I was looking for turned out

to be :"application.processMessages" as I was told over e-Mail.

However, OnIdle is a related thing and I need to learn about

that, too. I've been learning Delphi (in addition to my normal

work) for a couple of days, now. There is a lot of multi tasking

and re-entrancy related exploration I'll need to do before starting

to program with it for real.

: > How do you make more room to the speedbar. I don't seem to be able to move

: > the component palette very far to the right. On a high resolution screen

: > there is a lot of wasted real estate on the right, but I can't get all the

: > buttons I want onto the speedbar.

: >

: have you treid grabbing the edge of the speedbar on the right

: and dragging it right as far as possible? i put every speedbutton

: i could find in my speedbar...(G)

The "l" in "Tools" is as far as it goes. 29 buttons on it, I guess I

could add three if I grouped them differently.

Thanx for your help,

Wilhelm

From: The Green Meddler <kilgalen@tde.com>

Tom Cabanski <sig@teleport.com> wrote:

>

>

> > How do you yield control to other tasks? "DoEvents" in VB or "Sleep" in

> > ObjectPAL. I tried "WaitMessage", but that isn't it.

>

> It's the TApplication object's ProcessMessages event (typically invoked as:)

>

> Application.ProcessMessages

now THAT was well hidden! i looked for that for TWO WEEKS!!!!!!

grrrrrrrrr

GM


Visual Bascom [sic] - Equivalent of VB DoEvents
Equivalent of VB DoEvents

#1001.VB	From: rm_savard@pnl.gov (Rodney M Savard)

In article <3jl8a9$bh9@nyx10.cs.du.edu>, jgilbert@nyx10.cs.du.edu (Jeremiah

Gilbert) says:

>Does Delphi have a similar command to VB's "DoEvents()"?

>(releases a time slice to windows to prevent a lock in a loop)

Just make a call to the "Yield" API function.  It's in the Kernel and

has no parameters, nor does it return anything.  Hope this helps.

-------------------------------------------------------------------------

Rodney M. Savard                                        rm_savard@pnl.gov

Kennewick, Tri-Cities, WA                                       Get NTed!

From: Steve Teixeira <steixeir@borland.com>

rm_savard@pnl.gov (Rodney M Savard) wrote:

>

> In article <3jl8a9$bh9@nyx10.cs.du.edu>, jgilbert@nyx10.cs.du.edu (Jeremiah

Gilbert) says:

>

> >Does Delphi have a similar command to VB's "DoEvents()"?

> >(releases a time slice to windows to prevent a lock in a loop)

>

> Just make a call to the "Yield" API function.  It's in the Kernel and

> has no parameters, nor does it return anything.  Hope this helps.

>

You should not use Yield() unless your application is *guaranteed* not

to receive any messages (ie, your application contains no windows).

Instead, the way to do this in Delphi is to call Application.ProcessMessages.

ProcessMessage encapsulates a PeekMessage() loop, which is the correct

"API-way" to do this.

        -Steve Teixeira

         steixeir@borland.com


Delphi and VB Professional Toolkit v1

#1002.VB	From: Steve Teixeira <steixeir@borland.com>

tdutch@ix.netcom.com (Tim Dutcher) wrote:

>

> My company purchased Delphi recently to develop database front-ends

> to dBase and SQL Server tables. I'm disappointed in the functionality

> of the TDBGrid component (from the Data Controls page). The vertical

> scroll-bar does not adjust itself correctly - regardless of the

> number of records in the database (I've tried 100 to 10000 records).

> The scroll tab jumps to the middle of the vertical scroll bar and does

> not adjust itself until you're at the last record of the table. It's

> a sloppy implementation.

>

> First question: Has anyone else experienced this problem?

>

Tim, the only alternative to this is to count the number of records in

dataset everytime the scrollbar is updated.  This can exact a *BIG*

performance penatly depending on the backend SQL server.

        -Steve Teixeira

         steixeir@borland.com

From: Alan@abfl.demon.co.uk (Alan Wood)

In article: <794489355snz@kuczora.demon.co.uk>  paul@kuczora.demon.co.uk (Paul

Kuczora) writes:

>

> It occurs to me that quite a few people will be dragging out their old

> copy of Visual BASIC 1 and its associated toolkit, so that a few more

> VBXs can be added to the palette. I went about this a little rashly, and

> found that some things break and much is redundant. FWIW here are some

> tips and opinions:

>

As someone who is already using VB3 Pro, and thinking of getting Delphi,

I was wondering what the implications are in terms of VBXs when both of

these are installed. Does Delphi come with any VBXs, does it install

them in another section, or something else ?

  Alan Wood             I have mastered the programming,

 ~~~~~~~~~~~            now to get the programs working.

From: jreynd@unm.edu (john t UNM.HOSPITAL reynold)

>>In article: <794489355snz@kuczora.demon.co.uk>

>paul@kuczora.demon.co.uk (Paul

>>Kuczora) writes:

>

>>As someone who is already using VB3 Pro, and thinking of getting

>Delphi,

>>I was wondering what the implications are in terms of VBXs when both of

>>these are installed. Does Delphi come with any VBXs, does it install

>>them in another section, or something else ?

Another directory (except for the controls it installs in the VB

directory and in autoload.mak).  Why on earth would they do a stupid

thing like that anyway?

Delphi comes with its own components that make it CHILD'S PLAY to create

popup menus from ANYTHING, has help popups on buttons, makes Sheridan's

SSFormFX obsolete (always on top, toolbar creation is easy)...There's

enough stuff there to replace $$$ hundreds worth of the controls you

purchased that you can no longer use.  It's just better!

John Reynolds


Delphi's eqiv to VB's Setup Wizard

#1003.VB	From: abarbour@pipeline.com (Aaron Barbour)

In comp.lang.pascal "David R. Zangger" <drzangger@ccgate.dp.beckman.com>

said:

>Does Delphi have a setup wizard that is similar to Visual Basics?  I've

been

>seeing some stuff here about licensing issues but I'm not sure if that

relates

>to this or not?  I've searched the "lacking" manuals.

Since Delphi creates stand-alone executables, a Setup Wizard a la VB is not

really necessary.  If you use any .DLLs in your project, you are aware of

it and so know which files to include.

I agree that some sort of an application installation utility would be

nice, however.  I believe that a few 3rd party vendors sell some.

Aaron Barbour


Delphi Equivlant of SendKey()

#1004.VB	From: Steve Teixeira <steixeir@borland.com>

jeroenp@dragons.nest.nl (Jeroen Pluimers) wrote:

>

>

> Friday March 10 1995 22:48, gregs@mtjeff.com wrote:

>

>  gc> Is anyone aware of a Delphi Equivalent of sendKey().  I've been

>  gc> programming in ObjectPAL & VB3.0Pro & really miss my SENDKEYS command.

>

> Formally, this should be done trough a WH_JOURNALPLAYBACK hook. Most of the

> times however, you can perform the same using SendMessage(HWindow, wm_Char,

> Value,0);

>

> HWindow is the windows handle of the target window.

> Value is a Word where the high byte is 0 and the low byte is the ASCII value

of

> the charater to send.

>

>

> Jeroen

>

Jeroen,

I'm surprised you didn't do this the "Delphi Way..."  <g>

ComponentInstance.Perform(wm_Char, value, 0);

        -Steve Teixeira

         steixeir@borland.com

From: canalrun@aol.com (CanalRun)

>> ??? ComponentInstance.Perform(wm_Char, value, 0); ???

>>

>> Where do you find this stuff? I am trying Delphi, but unfortunately, I

am

>> not familiar with Object Pascal. I have seen other methods posted such

as

>> Application.Somthing() that also do simply amazing things. Where is

this

>> documented? Do I need to buy the $35 book to find this stuff?

>

> buy the manuals. i am, and i was in on the field test.

> most of this stuff comes from spending FAR too many hours searching

t> he online help....

> GM

I searched the on-line docs and could not find "ComponentInstance.Perform"

anywhere.

Has anyone else found it?

Where is it?

Thanks.

From: Steve Teixeira <steixeir@borland.com>

The Green Meddler <kilgalen@tde.com> wrote:

>

> canalrun@aol.com (CanalRun) wrote:

> >

> > Hello,

> >

> > ??? ComponentInstance.Perform(wm_Char, value, 0); ???

> >

> > Where do you find this stuff? I am trying Delphi, but unfortunately, I am

> > not familiar with Object Pascal. I have seen other methods posted such as

> > Application.Somthing() that also do simply amazing things. Where is this

> > documented? Do I need to buy the $35 book to find this stuff?

> >

> > Where should I get started?

> >

> > Thanks,

> > Barry.

> buy the manuals. i am, and i was in on the field test.

>

> most of this stuff comes from spending FAR too many hours searching

> the online help....

>

Actually, having written parts of the online help (don't flame me, only the

good

parts <G>), I learned most of what I know from GREPing the dickens out of the

RTL

and interacting with other Delphi users.

        -Steve Teixeira

         steixeir@borland.com

From: Steve Teixeira <steixeir@borland.com>

canalrun@aol.com (CanalRun) wrote:

>

> >> ??? ComponentInstance.Perform(wm_Char, value, 0); ???

> >>

> >> Where do you find this stuff? I am trying Delphi, but unfortunately, I

> am

> >> not familiar with Object Pascal. I have seen other methods posted such

> as

> >> Application.Somthing() that also do simply amazing things. Where is

> this

> >> documented? Do I need to buy the $35 book to find this stuff?

> >

> > buy the manuals. i am, and i was in on the field test.

> > most of this stuff comes from spending FAR too many hours searching

> t> he online help....

> > GM

>

> I searched the on-line docs and could not find "ComponentInstance.Perform"

> anywhere.

> Has anyone else found it?

> Where is it?

>

Perform() is doc'd in the Component Writer's Guide help (CWG.HLP).  Do a

"search all", and you should find it.

        -Steve Teixeira

         steixeir@borland.com

From: Steve Teixeira <steixeir@borland.com>

The Green Meddler <kilgalen@tde.com> wrote:

>

> Steve Teixeira <steixeir@borland.com> wrote:

> >

> > The Green Meddler <kilgalen@tde.com> wrote:

> > >

> > > canalrun@aol.com (CanalRun) wrote:

> > > >

> > > > Hello,

> > > >

> > > > ??? ComponentInstance.Perform(wm_Char, value, 0); ???

> > > >

> > > > Where do you find this stuff? I am trying Delphi, but unfortunately, I

am

> > > > not familiar with Object Pascal. I have seen other methods posted such

as

> > > > Application.Somthing() that also do simply amazing things. Where is

this

> > > > documented? Do I need to buy the $35 book to find this stuff?

> > > >

> > > > Where should I get started?

> > > >

> > > > Thanks,

> > > > Barry.

> > > buy the manuals. i am, and i was in on the field test.

> > >

> > > most of this stuff comes from spending FAR too many hours searching

> > > the online help....

> > >

> >

> > Actually, having written parts of the online help (don't flame me, only

the good

> > parts <G>), I learned most of what I know from GREPing the dickens out of

the RTL

> > and interacting with other Delphi users.

> >

> >     -Steve Teixeira

> >      steixeir@borland.com

> amen. grep rules. and steve, maybe (hint hint) borland should

> consider putting a direct grep functionality in the help system...

>

> GM

>

Actually, we have a tool kinda like that that ships with BC++4.5.  I'll ask

about

putting it into later versions of Delphi...

        -Steve Teixeira

         steixeir@borland.com

From: marwk@levels.unisa.edu.au

In article <795072615.AA05208@dragons.nest.nl.dragons.nest.nl>,

jeroenp@dragons.nest.nl (Jeroen Pluimers) writes:

> Friday March 10 1995 22:48, gregs@mtjeff.com wrote:

>

>  gc> Is anyone aware of a Delphi Equivalent of sendKey().  I've been

>  gc> programming in ObjectPAL & VB3.0Pro & really miss my SENDKEYS command.

>

> Formally, this should be done trough a WH_JOURNALPLAYBACK hook. Most of the

> times however, you can perform the same using SendMessage(HWindow, wm_Char,

> Value,0);

>

> HWindow is the windows handle of the target window.

> Value is a Word where the high byte is 0 and the low byte is the ASCII value

of

> the charater to send.

>

>

> Jeroen

>

Thanks - but how does one find out the handle of the window to send the keys

to?

--

Raymond Kennington                | Act in haste and repent at leisure

                                  | Code too soon and debug forever

University of South Australia     | ....Dale and Lily (I think)

Computer and Information Science  | Knobs, knobs everywhere,

Levels                            |        just vary a knob to think!

Pooraka 5095                      | ....Metamagical Themas, Hofsta"dter

South Australia


VB3 to Delphi converter?

#1005.VB	From: koterski@genghis (Steve Koterski)

Ian Piper (Ian@monty.demon.co.uk) wrote:

: In article: <795204034.AA05249@dragons.nest.nl.dragons.nest.nl>

bobs@dragons.nest.nl (Bob Swart)

: writes:

:     > A review on the Delphi Conversion Assistant will appear in an uncoming

issue of

:     > The Delphi Magazine, by the way...

:     >

: ..and how do I get this magazine...? Could you post or mail some details?

The Delphi Magazine

Tel/FAX: 44 (0) 181 460 0650

iTec, 41 Recreation Road

Shortlands BROMLEY

Kent BR2 0DY, UK

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


Equiv for VB's Form.Print?

#1006.VB	From: Reg Jacklin <jacklinr@cadvision.com>

>   Reg Jacklin <jacklinr@cadvision.com> writes:

>  Hi,

>

>

>  #1. What is the Delphi equivalent to VB's Form.Print  (more generally

<controlname>.Print)?

   [original question posted to comp.lang.pascal only]

>>>>

I found it, so I'll do a followup to my own post.  (I see I'm not the first;

given the state of the

Delphi manuals, I probably won't be the last either).

The answer is:  use the TextOut method of the Canvas object attached to the

form. Example:

{VB:} Form1.Print "I am a test string"

{Delphi:}  Form1.Canvas.TextOut (1,1,'I am a test string');  { X and Y are

text location }

Perhaps equally interesting is how I got there through the helps: not obvious.

While reading up on something totally different (Drawing graphics at run time,

Chapter 11),

I stumbled across the Canvas object.  Hmmm....

Search help for Canvas

Canvas Property:Click on 'Canvas Property for Forms and Paint Boxes'

Canvas Property {a different one}: Click on 'TCanvas' under Declarations

TCanvas Object: Click on Methods

TCanvas Object {also a different one}: click on a likely-looking method,

TextOut

And finally (ta dah)... the answer.

Well, I don't feel too bad about not being able to find it.  This is a long

distance from

Form1.Print.  And having two different help items with the same name really

adds to

the confusion.

Reg Jacklin

Contract Programmer / VB Instructor


'Unknown Identifier' error on second form?

#1007.VB	From: Reg Jacklin <jacklinr@cadvision.com>

Hi,

I am an experienced VB programmer, but brand new to Delphi and ve-r-r-r-y

rusty at Pascal.

I have a couple of questions whose answers are likely obvious to an

experienced Pascal

person, but are eluding me in the manuals and online help.  I'll post these as

separate messages

so the headers can be more relevant.

#2. Just got Delphi yesterday and started playing with it.  I set up a second

form, but no matter

how I tried to reference it or anything on it from an event on the first form,

I got 'Unknown Identifier'.

The statement, in the Click event of a button on form 1, was of the form

<object.property> := 'hello';

I tried <object.property> as:

Unit2.Form2.Label1.Caption

Form2.Label1.Caption

Label1.Caption

and got the same error every time.

Then I loaded the cbt_proj example (the only one I could find which was a

whole project),

and it got the same error in the line that says

 Application.CreateForm(TForm1, Form1);

 What am I missing here?

I'm running Windows for Workgroups (single user)  on a 75 Mhz 486 (AMD chip),

8M RAM.

Thanks in advance.

Reg Jacklin

Contract Programmer / VB Instructor

Thanks in advance.

Reg Jacklin

Contract Programmer / VB Instructor

From: dmurdoch@mast.queensu.ca (Duncan Murdoch)

In article <3kve17$rik@huey.cadvision.com> Reg Jacklin

<jacklinr@cadvision.com> writes:

>#2. Just got Delphi yesterday and started playing with it.  I set up a second

>form, but no matter

>how I tried to reference it or anything on it from an event on the first

form, I

>got 'Unknown Identifier'.

>The statement, in the Click event of a button on form 1, was of the form

><object.property> := 'hello';

>I tried <object.property> as:

>Unit2.Form2.Label1.Caption

>Form2.Label1.Caption

>Label1.Caption

>and got the same error every time.

The first two should have worked, but they depend on being in the unit

Unit2, or being in another unit (or your main program file) that "uses" Unit2.

I'd guess your problem is that you've forgotten to add Unit2 to the Uses

clause at the top of the unit where Form1 is defined.

The problem with the last one is that in a Form1 event, it would refer to

Form1.Label1; it sounds as though you don't have one of those.

Pascal has a strong idea of scoping, and Delphi has kept that.  In

Pascal things are only available if you explicitly make them available.

Delphi weakens this concept a bit in that it declares a few things for you,

but it doesn't declare everything.

Duncan Murdoch


VB ---> DELPHI porting???

#1008.VB	From: koterski@genghis (Steve Koterski)

John Michael Okeefe (jmokeefe@nachos.engr.ucdavis.edu) wrote:

:        I'm trying to port some VB code I have to DELPHI's flavor of

: object pascal. Specifically I'm trying to port VB's "exit do" command to

: DELPHI. Is there a way to prematurely end a for or do loop in DELPHI??

:         Wouldn't it be nice if there was a help file that would

: show equivalent commands in VB and DELPHI!!! :-) I would do it but I

: have no experience making help files! I did also read the VB2DELPHI.WRI

: file but it would be nice if you had a help file with word search and

: hypertext links so that you could look up a VB or DELPHI function and

: find its equivalent in the other language!

:

Look at the Break procedure. It breaks out of the currently processing

loop, and program flow picks up at the first command following the loop

construct.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


Delphi equivalent of VB control arrays

#1009.VB	From: rm_savard@pnl.gov (Rodney M Savard)

In article <3jm133$mhl@peaches.cs.utexas.edu>, turpin@cs.utexas.edu (Russell

Turpin) says:

>> What is the equivalent of a VB Control Array in Delphi?  How do I

>> make a control array at design time?

>See the current thread on dynamically cloning components.

Thanks, I took a look but didn't see what I was looking for. Synchronizing

the properties/events is no problem. I basically want to know how to make

the control VISIBLE once I create another instance of it!  Here's

something like what I have right now:

var

  Buttons:array [1..10] of TButton;

begin

  Buttons[1]:=TButton.Create(Form1);

  {how do I make the button visible?}

end;

-------------------------------------------------------------------------

Rodney M. Savard                                        rm_savard@pnl.gov

Kennewick, Tri-Cities, WA                                       Get NTed!

From: Steve Teixeira <steixeir@borland.com>

rm_savard@pnl.gov (Rodney M Savard) wrote:

>

> What is the equivalent of a VB Control Array in Delphi?  How do I make a

> control array at design time?

>

Every container component (ie, forms, panels, etc) has a built-in control

array called Components[].  Let's say you wanted to iterate over all the

edit controls in your form... you would do it like this:

procedure TForm1.IterateOverTEdits;

var

  i: longint;

begin

  for i := 0 to ComponentCount - 1 do

    if Components[i] is TEdit then { use RTTI to check type }

      DoSomeThingWithEdit(TEdit(Components[i])) { pass control to some func }

end;

        -Steve Teixeira

         steixeir@borland.com

From: rm_savard@pnl.gov (Rodney M Savard)

In article <3jn90t$och@druid.borland.com>, Steve Teixeira

<steixeir@borland.com> says:

>Every container component (ie, forms, panels, etc) has a built-in control

>array called Components[].  Let's say you wanted to iterate over all the

>edit controls in your form... you would do it like this:

Thanks, but I'm really wanting a way to create/destroy additional copies

of a control at runtime.  For example, a toolbar application that had

a variable number of buttons.

I think I know how to create additional controls in an array now, but

how do you make the control visible after you create it?

-------------------------------------------------------------------------

Rodney M. Savard                                        rm_savard@pnl.gov

Kennewick, Tri-Cities, WA                                       Get NTed!

From: Steve Teixeira <steixeir@borland.com>

rm_savard@pnl.gov (Rodney M Savard) wrote:

>

> In article <3jn90t$och@druid.borland.com>, Steve Teixeira

<steixeir@borland.com> says:

>

> >Every container component (ie, forms, panels, etc) has a built-in control

> >array called Components[].  Let's say you wanted to iterate over all the

> >edit controls in your form... you would do it like this:

>

> Thanks, but I'm really wanting a way to create/destroy additional copies

> of a control at runtime.  For example, a toolbar application that had

> a variable number of buttons.

>

> I think I know how to create additional controls in an array now, but

> how do you make the control visible after you create it?

>

> -------------------------------------------------------------------------

> Rodney M. Savard                                        rm_savard@pnl.gov

> Kennewick, Tri-Cities, WA                                       Get NTed!

Rodney,

When you create a control dynamically, you have to remember to do two things:

1. Assign a Parent (MyButton.Parent := Self { in one of your form's methods})

2. Set visible to True (MyButton.Visible := True).

You'll also need to adjust Left, Top, Width, Height, Caption, etc,

to make the button appear where and how you would like.

        -Steve Teixeira

         steixeir@borland.com

From: vincer@iaccess.za (Vince Risi)

In article <3jnj5b$i0v@bbs.pnl.gov>, rm_savard@pnl.gov (Rodney M Savard)

wrote:

> In article <3jn90t$och@druid.borland.com>, Steve Teixeira

<steixeir@borland.com> says:

>

> >Every container component (ie, forms, panels, etc) has a built-in control

> >array called Components[].  Let's say you wanted to iterate over all the

> >edit controls in your form... you would do it like this:

>

> Thanks, but I'm really wanting a way to create/destroy additional copies

> of a control at runtime.  For example, a toolbar application that had

> a variable number of buttons.

>

> I think I know how to create additional controls in an array now, but

> how do you make the control visible after you create it?

You do not have to create them in an array, you can let the component

you insert them into hold them in storage for you. Let us say you create

a tpanel Panel1. You can then create controls like tedit or tbutton with

   wEdit := tEdit.Create(Self);

   wEdit.Top := 20;

   ...

   Panel1.InsertControl(wEdit);

later on you could remove all the controls out of Panel1

   with Panel1 do begin

      for i := pred(ControlCount) downto 0 do begin

         wControl := Controls[i];

         RemoveControl(wControl);

         wControl.Destroy;

      end;

   end;

Vince

From: Steve Teixeira <steixeir@borland.com>

jwales@silver.ucs.indiana.edu (Jimmy -Jimbo- Wales) wrote:

>

> >> I'll give this a shot... I still haven't been able to USE a control I've

> >> created at run time.

> >>

> >> Rodney M. Savard                                        rm_savard@pnl.gov

> >> Kennewick, Tri-Cities, WA                                       Get NTed!

> >>

> >what problems are you having?

> >

> >GM

> >

>

> I think that Rodney may be having the same kinds of problems that I'm

> having.  (See my post under the other thread about control arrays.)

>

> What I'm interested in seeing is a simple example in which someone

> creates a label (or button) at runtime, and then displays it on a

> form.  Doesn't seem that hard, but I'm having trouble getting it to

> work.  Must be something simple that I'm missing...

>

> --Jimbo

>

procedure TForm1.CreateALabel;

begin

  with TLabel.Create(Self) do begin

    Parent := Self;

    Top := 10;

    Left := 10;

    Caption := 'Delphi rules';

    Visible := True;

  end;

end;

That otta do it!

        -Steve Teixeira

         steixeir@borland.com

From: rm_savard@pnl.gov (Rodney M. Savard)

In article <78EPlWsogFgS073yn@iaccess.za>, vincer@iaccess.za says...

>You do not have to create them in an array, you can let the component

>you insert them into hold them in storage for you. Let us say you create

>a tpanel Panel1. You can then create controls like tedit or tbutton with

I know I don't have to, but I WANT to have the controls in an array. :-)

>   wEdit := tEdit.Create(Self);

>   wEdit.Top := 20;

>   ...

>   Panel1.InsertControl(wEdit);

I'll give this a shot... I still haven't been able to USE a control I've

created at run time.

--

Rodney M. Savard                                        rm_savard@pnl.gov

Kennewick, Tri-Cities, WA                                       Get NTed!

From: The Green Meddler <kilgalen@tde.com>

ediss@teleport.com wrote:

>

>

> Am I barking up the wrong tree with this kind of classic object Pascal

> approach?  Seems like I read somewhere that we weren't "supposed" to rely

> so heavily on pointers anymore . . . maybe in PC Techniques?

>

>> ediss@teleport.com

the delphi documentation points out that most delphi identifiers

are already pointers, and do automatic dereferencing. i'm still

sorting through the language definition on this.

GM


Delphi mystery - Exception at Launch

#1000.INS	From: The Green Meddler <kilgalen@tde.com>

rothpn@oasys.dt.navy.mil (Pete Roth) wrote:

>

> Loaded Delphi onto my 486 DX2 D: drive from CDROM.  I attempt to launch

> Delphi. It gets through the Speedbar and the Object Inspector. At the

> component bar, it stops and posts a messagebox with the stop sign icon:

> Out of resources.  Click the OK button (!?), Delphi continues to load.

>

> When I try to do _anything_, D raises the EOutOfResources

> exception as a general protection fault, and closes itself down.

>

> A search of the D documentation reveals a single sentence related to

> this exception, which tells me I've run out of Windows handles.

>

> I reconfigured a few times, but really don't know in which direction

> to move next. Ideas appreciated. I'll call Borland this morning and

> post a solution to this poser if I find one.

>

>                              ###

> Grace + Peace

> rothpn@oasys.dt.navy.mil              alias: Peter N Roth

>              Excellence in Software Development

first, you need to get one of those gdi/user resource monitor

shareware thingies. i have one and i live by it!

second, i've found Delphi not to need that many resources (for

the desktop version at least), somewhere around 10% user and 15%

gdi. so something is weird somewhere.

keep us posted!

GM

From: atd@ix.netcom.com (Alan Daniels)

>rothpn@oasys.dt.navy.mil (Pete Roth) wrote:

>>

>> Loaded Delphi onto my 486 DX2 D: drive from CDROM.  I attempt to

>> launch Delphi. It gets through the Speedbar and the Object Inspector.

>> At the component bar, it stops and posts a messagebox with the stop

>> sign icon:

>> Out of resources.  Click the OK button (!?), Delphi continues to

>> load.

>>

>> When I try to do _anything_, D raises the EOutOfResources

>> exception as a general protection fault, and closes itself down.

>>

>> A search of the D documentation reveals a single sentence related to

>> this exception, which tells me I've run out of Windows handles.

>>

>> I reconfigured a few times, but really don't know in which direction

>> to move next. Ideas appreciated. I'll call Borland this morning and

>> post a solution to this poser if I find one.

I got the same thing too. The first thing I did was talk to Borland.

Their suggestions:

    1. Make sure you have 550K or greater conventional memory.

       And no, I don't know why a Windows tool would need this either.

    2. Make sure you have the latest and greatest copy of your

       Windows Video Driver. In the meantime, get your number of

       colors down to 16 or 256 (no 16- or 24-bit color), or go

       back to using the standard VGA driver.

I took care of these two things, and then didn't have a problem anymore.

Delphi now spins like a top. :-)

-------------

(Somebody who thinks Delphi rules...)

Alan Daniels.

atd@ix.netcom.com.

From: jeroenp@dragons.nest.nl (Jeroen Pluimers)

Monday March 06 1995 10:07, rothpn@oasys.dt.navy.mil wrote:

 rdnm> Loaded Delphi onto my 486 DX2 D: drive from CDROM.  I attempt to launch

 rdnm> Delphi. It gets through the Speedbar and the Object Inspector. At the

 rdnm> component bar, it stops and posts a messagebox with the stop sign icon:

 rdnm> Out of resources.  Click the OK button (!?), Delphi continues to load.

When searching for the cause, the best thing is to strip your system down to

the bare minimum and then start adding parts.

Windows is quite unstable, especially Video Drivers cause a lot of problems.

You might want to try using the Windows VGA driver to test.

Jeroen


Installing form CD Error

#1001.INS	From: dintersimone@wpo.borland.com (David Intersimone)

In article <3k4jc7$6ar@eis.wfunet.wfu.edu>, mudayja@wfu.edu (Jeffrey Muday)

says:

>

>bellb@randb.pprd.abbott.com writes:

>

>>I'm having a problem with Delphi.

>

>>When I install it from my CD, it stops in 2 places saying that a file is

>>corrupt and something about retrying. I say ok and it continues on. I have

>>tried this 5 times, it happens every time.

>

>ME TOO!  I had a devil of a time installing Delphi on my system.  After

>experiencing errors from the installation program, I copied the run-time

>image to my hard-drive and spent some time changing attributes and INI

>files.  I had some problems with the Interbase stuff so I tried

>installation again... The installation program told me I had "Checksum

>errors" I retried multiple times, and got through them eventually-- only

>after I stripped down the system, and altered my Shadow Ram CMOS

>configuration.  At first I blamed myself for the installation problems,

>but now I think the guilty finger should be pointed at whoever wrote

>Borland's installation program.  I have never had a problem installing any

>CD-ROM based software before.

If you have installation problems, call the borland customer service line and

return the defective CD.  we test them on multiple drives.  some drives just

don't work all the time.  Our operations people and our cdrom manufacturers

have not found any pattern for the few problems that are reported.  Must be

sunspots, cosmic rays or some other unknown chaos.

David I, Borland


Run Delphi from the CD!

#1002.INS	From: Allen Bauer <abauer@borland.com>

Doug Reinhart <reinhart@gate.net> wrote:

>

> I just got my copy of Delphi yesterday, and was somewhat overwhelmed by

> the SIZE of the install!  Has anyone worked out an INI file that might

> allow running a few of the less often used tools directly from the CD

> while still allowing the system to save / write to the hard disk as

> required?

>

> TIA

>

In your DELPHI.INI file add the following line to the [Globals] section

(add it if nessesary):

[Globals]

PrivateDir=c:\delphi\bin\

Or what ever directory you want to contain the default desktop and other

assorted files.  The desktop and project options for a project will

always be placed in the same directory as the .DPR file.

Allen Bauer.

Delphi Development


Delphi gives 'Out of System Resources' Error

#1003.INS	From: darlingr@america.com (Russell E. Darling)

In article <Pine.A32.3.91.950316190216.82947B-100000@seminole.gate.net>,

reinhart@gate.net says...

>

>After installing Delphi from the CDROM, I get OUT OF SYSTEM RESOURCES

>error when I start it up.  Now, before I get a lot of replys with

>suggestions to 'turn off other programs, wallpapers etc etc' be advised

>I've already been through all that with no success.

>

Our company received Delphi yesterday (03/16).  We tried installing it

on three different machines, but had problems with each one.  Our

problems include 'Out of System Resources' and GPF errors.

Borland's tech. support seems to think the problems are related to the

video cards. Each machine has a different video card (each with at least

1MB). The support rep. suggested that we update our drivers (in most

cases they are up-to-date) or consider "newer, standardized" video cards.

The problem occurs when Windows uses the OEM drivers in resolutions of

800x600 or greater.  If we put the systems in 640x480  (16 color) mode,

we can use Delphi.  Otherwise, we are out of luck.

I don't understand why Borland does not comply with Windows' video

standards.  Our company will not go to the expense to upgrade our video

cards (all of which are less than a year old) or spend any more time

than we already have trying to find the "latest" video drivers.  Most

of our developers will not work in 640x480 just to use Delphi.  As a

developer that primarily uses Borland Pascal 7.0 we had high hopes for

Delphi.  But now it looks like we will be using Visual C++ for our

latest windows projects.

Russell Darling

Software Engineer - R&D

Sales Partner Systems, Inc.

From: memorex@cats.ucsc.edu (Mathew Gyokers Eliot)

        The tech you got should have explained the situation to you:

        If it is a problem of the video driver, then how can you

hold Delphi responsible? All Delphi does is tell Windows to put

some buttons on the screen, etc, Windows then tells the driver

that Delphi wants some stuff put onto the screen, the driver

then is supposed to do it. Period.

        Delphi doesn't have a sinlge line of code that writes

to the video card so the screen display and any screen problems

aren't caused by delphi.

        It's a routine thing for drivers for video cards to be

exceedingly buggy and results in many problems for people like

GPF's and resource problems like you're running into.

        There is no 'video standard' for Windows apps, they don't

interact with the vid card at all.

        Go call the manufacturer of your vid card and ask for newer

drivers. They will ship you a disk, probably for free. The reason

for this is because video drivers are routinely flaky and so they

update them every few weeks.

--

Beavis kicks ASS! He KICKS 'em! Kicks, KICKS!  He rules, he RULES, RULES!!

From: earache@primenet.com (Earache)

>   What problems did you have?  I have that ATI Turbo Graphics Pro and it

> installed and is running fine.

>

> --Pete

I get problems if I'm in a resolution higher than 640x480x256 with my

speedstarPRO.

And anything I compile has problems too.

Nothing else that I run on my system has had a problem like that, so I

would have to think it's a problem with Delphi (BP7 works fine in

800x600x16M but Delphi won't).

earache


Installing Delphi - Delphi & Windows Resources Problem
Delphi & Windows Resources Problem

#1004.INS	From: jnhodges@nps.navy.mil (John N. Hodges)

In article 0022719B@postoffice.sandybay.utas.edu.au,

justin_t@postoffice.sandybay.utas.edu.au (Justin Thurley) writes:

>

>Ive just purchased Delphi but I cannot get the actual program "Delphi" to run

>completely. When I start the application I get an "Out of System Resources"

>error. I have a 20Mb perm. swapfile and have removed the majority of my

device

>drivers, and the problem persists.

>

>Has anyone got any ideas of how to overcome this problem.

>Borland in Australia couldnt help me.

>

Some folks have reported this problem, and it frequently is traced

back to old/bad video drivers.  Switch to vanilla Windows VGA and

see if the probelm goes away.  If so, ensure that you have the most

recent version of your video driver.  Some video board makers update

their drivers as often as weekly.

---

*   LT Nick Hodges, USN                     Naval Postgraduate School

*

*   jnhodges@nps.navy.mil                Information Technology Management

*

*   CIS: 71563,2250 AOL: NHodges                   Monterey, CA

*

*   The opinions expressed above are entirely my own and not the Navy's.

*

*   Visit my homepage:  http://vislab-www.nps.navy.mil/~jnhodges

*

From: keeper@netcom.com (Mark R. Johnson)

In article <justin_t.5.0022719B@postoffice.sandybay.utas.edu.au>,

   justin_t@postoffice.sandybay.utas.edu.au (Justin Thurley) wrote:

>

>Ive just purchased Delphi but I cannot get the actual program "Delphi" to run

>completely. When I start the application I get an "Out of System Resources"

>error. I have a 20Mb perm. swapfile and have removed the majority of my

device

>drivers, and the problem persists.

>

>justin_t@postoffice.sandybay.utas.edu.au

The 20MB swap file will probably not have any effect on your running

out of resources.  Most likely, you are running out of Graphic resources

(used for pens, brushes, bitmaps, etc.).  These resources are not swapped,

so the swap file makes little impact.  Does your system meet the minimum

requirements of 6MB RAM?  If so, are you running other graphics intensive

or windows intensive (i.e. lots of windows or controls) programs?

Are you using a hicolor or 256-color display at high resolution?

--Mark Johnson

______________________________________________________________________________

Mark R. Johnson     _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

Atlanta, GA USA    _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

keeper@netcom.com _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


Delphi Local - Accesing Paradox on the LAN

#1005.INS	From: koterski@genghis (Steve Koterski)

AROETH (aroeth@aol.com) wrote:

:       Please no flames on this....I'm waiting on a DELPHI newsgroup as we

: speak.

:      I have PDox5 currently installed on our Novell LAN.  When I installed

: DELPHI, it found the IDAPI/BDE files out on the LAN that are a part of

: PDox.  The install pgrm tried(unsuccessfully) to write to that directory

: and aborted.  This is no surprise since we have those directories write

: protected from the general user so that our critical data/setups are not

: disturbed.

:     My question is, can I have the DELPHI setup place its IDAPI/BDE files

: locally on my HD, with no conflicts later.  PDox still finds its IDAPI

: info on the F: drive with no problem....will DELPHI leave those files

: alone since I have designated its source for those files as C:\IDAPI?  I

: am trying to avoid any conflicts if both apps are running either

: concurrently or at separate times.

Delphi (and Paradox for Windows) finds the Borland Database Engine (BDE,

aka IDAPI files) using a settings in the WIN.INI file. There will be two

lines in an [IDAPI] section in the WIN.INI file:

   [IDAPI]

   CONFIGFILE01=C:\IDAPI\IDAPI.CFG

   DLLPATH=C:\IDAPI

Now, it is entirely possible to have two different IDAPI directories, one

for Delphi and one for Paradox for Windows. They can even be on different

drives or drive types (as in a network drive). However, where either

application will look for the BDE files will depend on the current values

for these settings in the WIN.INI file. So before starting either of these

two applications, you would need to change these settings to values

appropriate to the application about to be run.

This could be done by maintaining two copies of the WIN.INI file, each

with different settings. Or it could be done by an EXE you create in

Delphi that makes the change for you. The latter would probably be the

better choice as you would then need to only worry about keeping one

copy of WIN.INI up to date.

--

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

_/ Steve Koterski               _/   The opinions expressed here are    _/

_/ koterski@borland.com         _/         exclusively my own           _/

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

From: martynk@io.org (Martyn Kerluk)

In article <3lpiia$em5@newsbf02.news.aol.com>, AROETH at aroeth@aol.com

says...

>

>      Please no flames on this....I'm waiting on a DELPHI newsgroup as

we

>speak.

>

>     I have PDox5 currently installed on our Novell LAN.  When I

installed

>DELPHI, it found the IDAPI/BDE files out on the LAN that are a part of

>PDox.  The install pgrm tried(unsuccessfully) to write to that directory

>and aborted.  This is no surprise since we have those directories write

>protected from the general user so that our critical data/setups are not

>disturbed.

>    My question is, can I have the DELPHI setup place its IDAPI/BDE

files

>locally on my HD, with no conflicts later.  PDox still finds its IDAPI

>info on the F: drive with no problem....will DELPHI leave those files

>alone since I have designated its source for those files as C:\IDAPI?  I

>am trying to avoid any conflicts if both apps are running either

>concurrently or at separate times.

>

>Thanks

>

>AL

>*******************************************************************

>            AROETH@......any number of places.com

>

>*******************************************************************

MK> You should be able to run both versions of Idapi without conflict,

but why bother? The new Idapi is 100% compatible with pdox5.0, and is

better code, so I'd backup the  old idapi and overwrite it with the

Delphi idapi.

--

Martyn Kerluk

<><><><><><><>

http://www.io.org/~martynk/

...."I come to free the words" ....

..........Brion Gysin..............


Installing Delphi - Delphi & Windows Resources Problem
Delphi & Windows Resources Problem

#1006.INS	From: jnhodges@nps.navy.mil (John N. Hodges)

In article 0022719B@postoffice.sandybay.utas.edu.au,

justin_t@postoffice.sandybay.utas.edu.au (Justin Thurley) writes:

>

>Ive just purchased Delphi but I cannot get the actual program "Delphi" to run

>completely. When I start the application I get an "Out of System Resources"

>error. I have a 20Mb perm. swapfile and have removed the majority of my

device

>drivers, and the problem persists.

>

>Has anyone got any ideas of how to overcome this problem.

>Borland in Australia couldnt help me.

>

Some folks have reported this problem, and it frequently is traced

back to old/bad video drivers.  Switch to vanilla Windows VGA and

see if the probelm goes away.  If so, ensure that you have the most

recent version of your video driver.  Some video board makers update

their drivers as often as weekly.

---

*   LT Nick Hodges, USN                     Naval Postgraduate School

*

*   jnhodges@nps.navy.mil                Information Technology Management

*

*   CIS: 71563,2250 AOL: NHodges                   Monterey, CA

*

*   The opinions expressed above are entirely my own and not the Navy's.

*

*   Visit my homepage:  http://vislab-www.nps.navy.mil/~jnhodges

*

From: keeper@netcom.com (Mark R. Johnson)

In article <justin_t.5.0022719B@postoffice.sandybay.utas.edu.au>,

   justin_t@postoffice.sandybay.utas.edu.au (Justin Thurley) wrote:

>

>Ive just purchased Delphi but I cannot get the actual program "Delphi" to run

>completely. When I start the application I get an "Out of System Resources"

>error. I have a 20Mb perm. swapfile and have removed the majority of my

device

>drivers, and the problem persists.

>

>justin_t@postoffice.sandybay.utas.edu.au

The 20MB swap file will probably not have any effect on your running

out of resources.  Most likely, you are running out of Graphic resources

(used for pens, brushes, bitmaps, etc.).  These resources are not swapped,

so the swap file makes little impact.  Does your system meet the minimum

requirements of 6MB RAM?  If so, are you running other graphics intensive

or windows intensive (i.e. lots of windows or controls) programs?

Are you using a hicolor or 256-color display at high resolution?

--Mark Johnson

______________________________________________________________________________

Mark R. Johnson     _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

Atlanta, GA USA    _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

keeper@netcom.com _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


Run-Time Errors

#00000001.TBL	From Lloyds Help File

Error #	Error Message

1	Invalid function number

2	File not found

3	Path not found

4	Too many open files

5	File access denied

6	Invalid file handle

12	Invalid file access code

15	Invalid drive number

16	Cannot remove current directory

17	Cannot rename across drives

100	Disk read error

101	Disk write error

102	File not assigned

103	File not open

104	File not open for input

105	File not open for output

106	Invalid numeric format

200	Division by zero

201	Range check error

202	Stack overflow error

203	Heap overflow error

204	Invalid pointer operation

205	Floating point overflow

206	Floating point underflow

207	Invalid floating point operation

210	Object not initialized

211	Call to abstract method

212	Stream registration error

213	Collection index out of range

214	Collection overflow error

215	Arithmetic overflow error

216	General protection fault

Error #	Error Message

{This code came from Lloyd's help file!}


TextToFloat bug when called from a dll

#00000001.BUG	From KWolak@mail.cbf.com Thu Aug 24 13:09:29 1995

tpigden@cix.compulink.co.uk ("Tim Pigden") wrote:

>The following behaves very oddly when called from a non-delphi dll.

>

>function OpkDelphi2(const s1, s2: pchar; d1, d2: double): double;

>

>  procedure test;

>  var

>    d: double;

>    s: string;

>  begin

>    try

>    Messagedlg('decimal separator is <' + DecimalSeparator + '>',

>mtWarning, [mbOk], 0);

>    d := 1.22;

>    s := FloatToStr(d);

>    d := StrToFloat(s);

>    Messagedlg('d is <' + format('%f', [d]) + ' string ' + s + '>',

>mtWarning, [mbOk], 0);

>    result := 0

>    except

>      on e: exception do

>      Messagedlg('exception is ' + e.message, mtWarning, [mbOk], 0);

>    end;

>  end;

>begin

>  test;

>  test

>end;

>

>On the first call to the test procedure it fails with an exception saying

>that the string "1.22" is not a valid float (In french it claims that the

>string 1,22 is not valid). However, the second call to test succeeds in

>the expected manner. This strikes me as very peculiar. Is there some

>horrible bug in the rtl function TextToFloat? I'm afraid my assembler is

>non-existent so I can't check.

>

This is a known bug.  The problem is that the TextToFloat procedure (found in FFMT.ASM,

if you have the VCL Source) tries to access a global variable with the app's DSeg loaded

rather than the DLL's DSeg.  If you have the source, you can work-around this problem by

inserting a POP DS instruction immediately prior to the call to Power10 in the

TextToFloat proc.  You must also remove the POP DS instruction found immediately prior to

the @@8: label in TextToFloat.  I'm afraid there is currently no work-around if you don't

have the VCL source.

     -Steve Teixeira

      steixeir@borland.com


Bounds-Checker found memory leaks in Delphi programs!

#1000.BUG	From: jreynd@unm.edu (john t UNM.HOSPITAL reynold)

In article <3k6ktl$555@idefix.eunet.fi>,

Jukka Kemppainen  <jukka.kemppainen@martis.fi> wrote:

>I think I have found a memory leakage problem from VCL library!

>

>Why and how I found the possible problem

>----------------------------------------

>

[snip]

>

>Now I am starting to use Delphi and one of the first things I

>checked was the previous 'dream': can programs that use VCl

>handle allocations and deallocations properly. To test it I

>wrote a simple VCL test program with a single TButton object,

>nothing else. When I  ran the corresponding EXE file using

>Bounds-Checker 2.0, it created the following report:

[deleted]

>

>      -------------                   ----       ----------------

>      KERNEL!GLOBALALLOC              08192      0007:24D1

>      KERNEL!GLOBALALLOC              01024      0005:13EE

>

>

>> !!!!!!!!!!!!!!!!!!!!! is this ok? !!!!!!!!!!!!!!!! by jkemp

>

[more stuff deleted]

>

>The report shows clearly that two blocks of memory is not

>released when the program is closed! The memory addresses refer

>to code segments inside VCL library (There is also a API failure

>message...). You can get similar report of any BP7 OWL program.

>

>

>Is this a problem?

>------------------

This is something I've been wondering about, not having reached that

point in skill yet, but I think you just answered my question.  Most

likely (someone else knows this so please tell), when you close a program

by dblclicking the control box, the program is basically 'nuked'.  What I

think is required is for all forms to be explicitly unloaded and certain

resources returned to the system in the destroy (??) event before you

allow the program to exit.

Visual Basic has a similar problem so I was wondering if Delphi does.

I'm fairly sure that you just answered my question.  Does anyone know for

sure?

John Reynolds


Finally, at last at last!

#1001.BUG	From: A Blumsohn@shef.ac.uk (A Blumsohn)

In article <3k83i1$rik@ixnews4.ix.netcom.com>, Drglance@ix.netcom.com

(Raistlin) says:

>I know this is trivial, but I ran the interactive tutorial

>on creating a program and guess what????  During the creation, it would

>not input the code to put words in the listbox!  IS it a fluke on my

>Delphi, or does it show up on others?

No this happened on 2 machines that I used. One of the example programs

(Fish database) also crashed rather spectacularly on one machine. On the

whole Delphi is superb, but surely these problems should have been

easily detectable during the beta phase. I have come across a number

of other mysteries (eg. the installation program placed > 48MB of

files on my hard disk after saying that it would place 32MB).

It is also difficult to understand why Borland would not want to

place a rather larger amount and variety of sample code on their disk,

including some complete applications to show off their product.


Minimising Child Window

#1002.BUG	From: GREGORY MCBRIDE <mcbride@gaul.csd.uwo.ca>

csi063@coventry.ac.uk (Simon Love) wrote:

>

> Has anybody had the problem with delphi caused by minimising a child window

> generated by the MDI expert.

>

I read on compuserve that this is a known problem. They said it only occurs at

design time

and will not cause GPF's at run time. Their cure for now was not to minimize a

child window

when in design mode.

--greg


IDE BUG ?

#1003.BUG	From: rothpn@oasys.dt.navy.mil (Pete Roth)

1. Add your favorite (external) editor to the Delphi Tools menu.

Set macros appropriately. (e.g., $SAVE $EDNAME)

2. Activate the editor on the current file in the IDE editor.

3. Alter and save the file, return to the IDE.

4. BUG! IDE is unaware that the file has changed!

                             ###

Grace + Peace

rothpn@oasys.dt.navy.mil              alias: Peter N Roth

             Excellence in Software Development


Another Delphi IDE BUG

#1004.BUG	From: Chuck Jazdzewski <cjaz@borland.com>

> Adding units to projects

> ========================

>

> BUG: Adding unit(s) to a project removes the first characters

> from the body of the main program.

>

> For example, old program:

>

> begin

>   Application.CreateForm(TForm1,Form);

>   Application.Run;

> end.

>

> Add a unit. old program becomes

>

> begin

>   Application.CreateForm(TForm1,Form);

>   plication.Run; {<- missing chars}

> end.

>

> My system: Micron (defective) Pentium, Matrox video drivers.

> mucho memory.

I couldn't reproduce this.  What am I missing.  I tried the steps you gave

to no avail.

Chuck Jazdzewski (cjaz@borland.com)

Delphi Development

From: keeper@netcom.com (Mark R. Johnson)

>> Adding units to projects

>> ========================

>>

>> BUG: Adding unit(s) to a project removes the first characters

>> from the body of the main program.

>>

>> For example, old program:

>>

>> begin

>>   Application.CreateForm(TForm1,Form);

>>   Application.Run;

>> end.

>>

>> Add a unit. old program becomes

>>

>> begin

>>   Application.CreateForm(TForm1,Form);

>>   plication.Run; {<- missing chars}

>> end.

My system is performing similarly.  Here is a detailed description

of the problem:

I. Saving a new project:

  1. I open a new project, open the project file in the code window,

     and immediately press Run.

   - I am prompted to save Unit1.

  2. I select a new directory (C:\TEMP) and hit OK.

   - The Project1.DPR file is modified to give the full path of Unit1

     ("Unit1 in 'C:\TEMP\UNIT1.PAS'").  In making this modification,

     the first letter of "Application.Run" is deleted.  I am then

     prompted to save Project1.DPR.

  3. I select the same directory (C:\TEMP) and hit OK.

   - The Project1.DPR file is again modified to return to a relative

     path to Unit1 ("Unit1 in 'UNIT1.PAS').  In making this modification,

     the second letter of "Application.Run" is deleted.  The compile

     begins, and chokes on "plication.Run".

  4. At this point, I typically correct the line and continue about

     my business.  Everything continues to work fine until I add a

     new form (below).

II. Adding a new form:

  1. I press the "New Form" button to add a new form.

   - The new form is added, and the code editor shows the corresponding

     new unit.

  2. I switch back to the Project1.DPR file listing.

   - The uses clause has been modified to show Unit2 ("Unit2 in

     'L:\DELPHI\UNIT2.PAS'") and an Application.CreateForm() call

     has been added.  In addition, another letter has been deleted

     from the Application.Run line (or whatever line happens to

     immediately follow the Application.CreateForm() calls).

III. Deleting a form:

  If I delete a form (i.e. by closing the code editor page without

  ever having saved the form), a letter is deleted from the line

  immediately following the Application.CreateForm() listings.

*** Possible cause:

  My preference is to use the "IDE Classic" keymapping with "Persistent

  blocks" unchecked and "Overwrite blocks" checked.  If I set "Persistent

  blocks" to CHECKED and "Overwrite blocks" to UNCHECKED, I can initially

  add new forms without characters being deleted.  However, starting

  a new project with those settings still deletes characters, as does

  removing a form.  In addition, once a form has been removed, the

  "Persistent blocks" setting no longer affects the deleting of characters

  (i.e. they always get deleted).

I hope this helps you narrow down the possible culprit.  If any more

information is needed, I would be happy to provide it.

--Mark Johnson

______________________________________________________________________________

Mark R. Johnson     _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

Atlanta, GA USA    _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

keeper@netcom.com _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

From: Steve Teixeira <steixeir@borland.com>

keeper@netcom.com (Mark R. Johnson) wrote:

>

> >> Adding units to projects

> >> ========================

> >>

> >> BUG: Adding unit(s) to a project removes the first characters

> >> from the body of the main program.

> >>

> >> For example, old program:

> >>

> >> begin

> >>   Application.CreateForm(TForm1,Form);

> >>   Application.Run;

> >> end.

> >>

> >> Add a unit. old program becomes

> >>

> >> begin

> >>   Application.CreateForm(TForm1,Form);

> >>   plication.Run; {<- missing chars}

> >> end.

>

> My system is performing similarly.  Here is a detailed description

> of the problem:

>

> I. Saving a new project:

>

>   1. I open a new project, open the project file in the code window,

>      and immediately press Run.

>    - I am prompted to save Unit1.

>   2. I select a new directory (C:\TEMP) and hit OK.

>    - The Project1.DPR file is modified to give the full path of Unit1

>      ("Unit1 in 'C:\TEMP\UNIT1.PAS'").  In making this modification,

>      the first letter of "Application.Run" is deleted.  I am then

>      prompted to save Project1.DPR.

>   3. I select the same directory (C:\TEMP) and hit OK.

>    - The Project1.DPR file is again modified to return to a relative

>      path to Unit1 ("Unit1 in 'UNIT1.PAS').  In making this modification,

>      the second letter of "Application.Run" is deleted.  The compile

>      begins, and chokes on "plication.Run".

>   4. At this point, I typically correct the line and continue about

>      my business.  Everything continues to work fine until I add a

>      new form (below).

>

> II. Adding a new form:

>

>   1. I press the "New Form" button to add a new form.

>    - The new form is added, and the code editor shows the corresponding

>      new unit.

>   2. I switch back to the Project1.DPR file listing.

>    - The uses clause has been modified to show Unit2 ("Unit2 in

>      'L:\DELPHI\UNIT2.PAS'") and an Application.CreateForm() call

>      has been added.  In addition, another letter has been deleted

>      from the Application.Run line (or whatever line happens to

>      immediately follow the Application.CreateForm() calls).

>

> III. Deleting a form:

>

>   If I delete a form (i.e. by closing the code editor page without

>   ever having saved the form), a letter is deleted from the line

>   immediately following the Application.CreateForm() listings.

>

> *** Possible cause:

>

>   My preference is to use the "IDE Classic" keymapping with "Persistent

>   blocks" unchecked and "Overwrite blocks" checked.  If I set "Persistent

>   blocks" to CHECKED and "Overwrite blocks" to UNCHECKED, I can initially

>   add new forms without characters being deleted.  However, starting

>   a new project with those settings still deletes characters, as does

>   removing a form.  In addition, once a form has been removed, the

>   "Persistent blocks" setting no longer affects the deleting of characters

>   (i.e. they always get deleted).

>

> I hope this helps you narrow down the possible culprit.  If any more

> information is needed, I would be happy to provide it.

>

Try turning off "Optimal Fill" in Options|Environment|Editor Options.  Does

that work?

        -Steve Teixeira

         steixeir@borland.com


Image Editor Bug?

#1005.BUG	From: Marc@landscap.demon.co.uk (Marc Palmer)

In article: <795677422.AA05325@dragons.nest.nl.dragons.nest.nl>

jeroenp@dragons.nest.nl (Jeroen Pluimers) writes:

> Saturday March 18 1995 21:14, Marc@landscap.demon.co.uk wrote:

>  > The Delpi Image Editor doens't seem to save 256 color BMPs properly.

>

> What video drivers do you use?

ATI Mach 32

> BTW: If you have Resource Workshop, it is much better than the Image Editor.

> Use that one in stead.

Yes I do have it. It's not a small (RAM wise) as Image Editor and besides,

if something's there why not use it? Answer - because it doesn't work!

The Image Editor also doesn't always 'Cut' when you want it to. Also,

it crashes with a GPF in my video driver when I try to fill with a pattern.

********************************************************************

* Marc P.                               E-Mail me for PGP 2.6 key  *

*                                                                  *

* "Most of the ideas I have at the moment have to do with things   *

* that are completely impossible, so I am wary about sharing them. *

* They are, however, the only thoughts I have." - Dirk Gently      *

********************************************************************


DELPHI - Problem with OwnerDrawn TOutline

#1006.BUG	From: Marc@landscap.demon.co.uk (Marc Palmer)

In article: <kvlahos.16.00174355@lbs.lon.ac.uk>  kvlahos@lbs.lon.ac.uk

(Kiriakos Vlahos) writes:

>

> I have a problem with owner drawn TOutlines.  They don't even call the

> DrawItem event handler at run time.  It works fine with TListBoxes etc.  I

> wonder whether this is a bug.  I am waiting for the VCL source code to find

> out.  Any help from anybody?

Are you *sure* you've set the Ownder Draw property?

********************************************************************

* Marc P.                               E-Mail me for PGP 2.6 key  *

********************************************************************

From: Marc@landscap.demon.co.uk (Marc Palmer)

Subject: Re: DELPHI - Problem with OwnerDrawn TOutline

Date: Thu, 23 Mar 1995 00:33:02 +0000

In article: <kvlahos.16.00174355@lbs.lon.ac.uk>  kvlahos@lbs.lon.ac.uk

(Kiriakos Vlahos) writes:

>

> I have a problem with owner drawn TOutlines.  They don't even call the

> DrawItem event handler at run time.  It works fine with TListBoxes etc.  I

> wonder whether this is a bug.  I am waiting for the VCL source code to find

> out.  Any help from anybody?

>

I just got the same problem. I'm waiting for the VCL source too. Will

we be able to rebuild the VCL form the source?

********************************************************************

* Marc P.                               E-Mail me for PGP 2.6 key  *

********************************************************************

From: eblood@infonaut.com (Eric Blood)

Subject: Re: DELPHI - Problem with OwnerDrawn TOutline

Date: 22 Mar 1995 16:26:05 -0700

Marc Palmer (Marc@landscap.demon.co.uk) wrote:

: In article: <kvlahos.16.00174355@lbs.lon.ac.uk>  kvlahos@lbs.lon.ac.uk

(Kiriakos Vlahos) writes:

: >

: > I have a problem with owner drawn TOutlines.  They don't even call the

: > DrawItem event handler at run time.  It works fine with TListBoxes etc.  I

: > wonder whether this is a bug.  I am waiting for the VCL source code to

find

: > out.  Any help from anybody?

: Are you *sure* you've set the Ownder Draw property?

: ********************************************************************

: * Marc P.                               E-Mail me for PGP 2.6 key  *

: ********************************************************************

I'm quit sure he probably did set the Owner Draw style.  I encountered

the same problem.  After tracing through the VCL source code I found

two problems I would definitely call bugs and a third which I personally

consider a design bug.  All three are only applicable to the TOutline

class when Ownerdraw is being used.  As soon as I get it properly

organized I am planning on sending a bug report to Borland on it.

Eric Blood


TOutLine OnDraw Event

#1007.BUG	From: Marc@landscap.demon.co.uk (Marc Palmer)

In article: <3lk7vg$3l2@condor.ic.net>  rudyj@ic.net writes:

>

> Has anyone sucessfully implemented an OwnerDraw TOutLine component?

> It doesn't seem as if the OnDraw event ever happens.....

No - it doesn't ! There is a bug in the VCL. Got a fixed version of

the source from someone on this group ( I can't remember who). The

problem is that it is still not fixed properly. When you expand

a node it flickers constantly.

********************************************************************

* Marc P.                               E-Mail me for PGP 2.6 key  *

*                                                                  *

* "Most of the ideas I have at the moment have to do with things   *

* that are completely impossible, so I am wary about sharing them. *

* They are, however, the only thoughts I have." - Dirk Gently      *

********************************************************************


TStringList.Find doesn't work!

#1008.BUG	From: Marc@landscap.demon.co.uk (Marc Palmer)

If you fill a TStringList with strings and call Find('something') when

you know that 'something' is in there (i.e. you can see it in your

watches window as MyList[3] or something like that), you don't always

get a True result back!!!!! I took out the call to Find and replaced it

with a simple FOR loop that goes through all entries in the list, and

that *works*every*time* !!!!!

BUGBUGBUGBUGBUGBUGBUGBUGBUGBUGBUGBUGBUGBUG!

My source code implements an array property with a string as the index.

I use this string to find a value in the FFields data member (a

TStringList) using Find (I wish!). If a match is found, the function

returns the corresponding value from the FValues TStringList. This is

all of little consequence but helps to clarify the source code below.

Oh well....here's the source excerpt:

function TMyClass.GetField(Index : string) : string;

var

  j : Integer;

begin

  Result := naNoField; { this equates to a constant in my code }

{ this is code that DOES work but I'd rather use Find because it's

  there! }

  for j := 0 to FFields.Count-1 do

    if FFields[j] = Index then

    begin

      Result := FValues[j];

      Break;

    end else Inc(j);

  { This is the code that *does*not*work* !!! Field returns FALSE

    even when I can see in the debugger that there is an *exact*

    match in the FFields array.

      if FFields.Find(Index, i) then Result := FValues[i]

      else Result := naNoField;

  }

end;

********************************************************************

* Marc P.                               E-Mail me for PGP 2.6 key  *

*                                                                  *

* "Most of the ideas I have at the moment have to do with things   *

* that are completely impossible, so I am wary about sharing them. *

* They are, however, the only thoughts I have." - Dirk Gently      *

********************************************************************


OFFICIAL BUG (Ctl32v2.dll)

#512.BUG	From KWolak@mail.cbf.com Tue Dec 12 14:07:30 1995

On 11 Dec 1995, Simon Love wrote:

> It has been found and confirmed by Borlands Support team that there is a bug

> in the Startup code included in every Delphi application created that causes

> the application to GPFault before it reaches any of the application's code.

>

> If the application is run on a machine that does not have a suitable Microsoft

> 3D Custom Control DLL ( ctl3dV2.dll ) the application will GPF.  No nice error

> message is displayed, the developer is just left debugging his code!

My visual app runs fine with no ctl3dv2.dll present.

--

Sam Liddicott                  |   Nothing I say is to be attributed as

Campbell Scientific Ltd.       | a company statement or representation.

14-20 Field Street, Shepshed,  *----------------------------------------

Leicestershire,                             Phone: +44 (0) 1509 601141

United Kingdom. LE12 9AL                    Fax:   +44 (0) 1509 601091


Delphi process threads

#1000.UPD	From: Steve Teixeira <steixeir@borland.com>

mac@zeus.hsrc.ac.za (Malcolm Coulter) wrote:

>

> Does anyone know if Delphi for Windows95 will implement threads ( other than

> what may be available directly through the Win32 API) ?

32-bit Delphi will support threads.  I don't have any details at this time.

        -Steve Teixeira

         steixeir@borland.com


Clock.exe GPF

#1000.UNS	From: dlam@zeta.org.au (David Lam)

Please help!

I'm writing an app in delphi that is trying to do these:

1)      use GetWindowLong to the Desktop window to get event handling

        function.

2)      using SetWindowLong, replace the Desktop winproc with one of my

        function.

3)      My event handler will do something on a right mouse down, other

        messages will be passed to the original Desktop handler.

Everything works fine. For example I can show a form or a

Application.MessageBox on the right mouse click on the Desktop. And if I

left double-click I get the Task List (because I pass that messages to

the original event handler). The problem is that if I have some other

apps(eg clock.exe) iconized, and I retore it (by menu or left-dbl-click),

I will get a GPF saying "clock.exe cause GPF in module myapp.exe", where

myapp.exe is the app I am writing in Delphi.

I complied with SmartCallback, Force Far Calls, the following is the

relevent codes:

function NewHandler(hw: HWnd; msg: integer; wp: word; lp: longint)

: longint; export;

uses WinProcs, WinTypes, Messages;

type

        THandler = function(hw: HWnd; msg: integer; wp: word; lp: longint)

        : longint;

var

        OriginalHandler: TFarProc;

function NewHandler(hw: HWnd; msg: integer; wp: word; lp: longint)

: longint;

begin

  case msg of

  WM_RBUTTONDOWN:

      begin

          Application.MessageBox('Welcome to Delphi!', 'Message',

          mb_OKCancel + mb_DefButton1);

          result := 0;

      end

  else {case}

     NewHandler := THandler(OriginalHandler)(hw, msg, wp, lp);

  end {case};

end;

{This is the procedure I add my NewHandler to Desktop}

procedure AddHandler;

var

   Desktop: HWnd;

   newfunc: TFarProc;

begin

     Desktop := GetDesktopWindow;

     OriginalHandler := TFarProc(

                SetWindowLong(Desktop, GWL_WNDPROC, longint(@NewHandler))

                );            {I try using Addr() instead of @, but no help}

end;

Any help will be appreicated. Thanks in advance.


Delphi components broken in Warp

#1001.UNS	From: cbrown@access4.digex.net (Carl Brown)

:  > Anycase, this does not appear to be a WARP problem anymore -- but, a

:  > driver problem.

: There is probably something in they way here.

: version of DOS and Windows, then reinstall Delphi and try again.

Yep,

Reinstalled Windows and now everything is OK...  Still haven't gotten

Windows running under OS/2 -- may not even bother.

Lagged -- So -- that's all for now.

-Carl


How to derive class that accepts data on creation?

#1002.UNS	From: ediss@teleport.com

I'm trying to implement a new control class.  In the class def'n in the

unit's interface section I have:

type

  tNewControl = class(tGraphicControl)

  private

    [...stuff...]

  protected

    [...stuff...]

  public

    constructor Create(AOwner : tComponent; Data : Pointer; N : Integer);

      Override;

  published

    [...stuff...]

  end;

Then in the implementation section:

constructor tNewControl.Create(AOwner : tComponent;

                               Data : Pointer; N : Integer);

  begin

    [...stuff...]

  end;

This generates a compile-time error 131 (Header does not match previous

definition) located at the beginning of the word "Override".  What is

the correct way to create a control class that accepts data on creation?

Scott

--


Creating DB Tables in delphi

#1003.UNS	From: mfrisch@r-node.io.org (Mike Frisch)

James Sanders (sandersj@brutus.nctsl.navy.mil) wrote:

: The following code is copied from the Delphi Help File 'CreateTable' item.

: with Table1 do

:   begin

:   Active := False;

:   DatabaseName := 'Delphi_Demos';

:   TableName := 'CustInfo';

:   TableType := ttParadox;

:   with FieldDefs do

:     begin

:     Clear;

:     Add('Field1', ftInteger, 0);

:     Add('Field2', ftInteger, 0);

:     end;

:   with IndexDefs do

:     begin

:     Clear;

:     Add('Field1Index', 'Field1', [ixPrimary, ixUnique]);

:     end;

:   CreateTable;

:   end;

: I wanted to see this in action, so I made a new form, put a table control on

it, and named

: the table object 'table1'.  When I try and run the program, I receive errors

in the

: COPIED HELP EXAMPLE...  The errors are concerning the ADD method.  Help!

        Thanks to receiving the VCL source from Borland just yesterday, I

was able to figure out that the Add method for the FieldDefs object

actually has an undocumented parameter which prevents it from compiling.

The last paramter is a boolean field to determine whether or not the

field is mandatory.  For most intents and purposes in testing, this can

be set to false.  However, I am still experiencing problems with this

code.  I am trying to write an application which creates a new DB table,

but when the "CreateTable" call is made, the system GPFs.  To me, this

would indicate something is incomplete with the TTable structure.  I hope

somebody (from Borland, perhaps) can help...

Mike.

--

--------------------------------------------------------------------

  Mike Frisch                             Internet: mfrisch@io.org

  Northstar Technologies                    Compuserve: 76620,2534

  Newmarket, Ontario, Canada


StrAlloc anomaly?

#1004.UNS	From: Marc@landscap.demon.co.uk (Marc Palmer)

Hi, here's something wierd....

The Delphi help file says this when you look up StrAlloc :

function StrAlloc( Size : Word) : PChar;

Description

This function allocates a buffer for a null-terminated string with

a maximum length of Size - 1 (1 byte must be reserved for the

termination character). The maximum value of Size is 65,526. The

result points to the location where the first character of the string

is to be stored. A 16-bit number giving the total amount of memory

allocated is stored in the two bytes preceding the first character; it

is equal to Size + 2. If space for a string is allocated with StrAlloc,

it should be deallocated via StrDispose.StrAlloc is used by NewStr and

is a general purpose routine.

Ok - now notice the bit about the first two bytes (*preceding* the

first character which is at p[0]). I happened to see while debugging

that after my StrAlloc'd null-term string is finished with and I call

StrDispose on it, the first two characters of the *string* get garbled.

That's alright because I don't need them anymore, but it just seems odd.

Surely disposing the string shouldn't change it's contents? I'm

wondering if this is something to do with a GPF I'm getting....

I could have a bug in my code, but this definitely happens.

********************************************************************

* Marc P.                               E-Mail me for PGP 2.6 key  *

*                                                                  *

* "Most of the ideas I have at the moment have to do with things   *

* that are completely impossible, so I am wary about sharing them. *

* They are, however, the only thoughts I have." - Dirk Gently      *

********************************************************************


Mousecursor changing wierd....

#1005.UNS	From: Marc@landscap.demon.co.uk (Marc Palmer)

If I change the Cursor property for a form to crHourGlass, it works

fine, but when I move the mouse (at run time) over other controls like

buttons + listboxes, the cursor changes back to the arrow! This is no

good!  How can I get around this and is it a bug? Yes, my controls do

have the Cursor property set to crDefault.

********************************************************************

* Marc P.                               E-Mail me for PGP 2.6 key  *

*                                                                  *

* "Most of the ideas I have at the moment have to do with things   *

* that are completely impossible, so I am wary about sharing them. *

* They are, however, the only thoughts I have." - Dirk Gently      *

********************************************************************


DBE config for Access Tables

#1006.UNS	From: mwj@nyc.pipeline.com (Jin Mai)

In comp.lang.pascal "David S. Zaret" <juggler@mcs.com> said:

>Jin Mai (mwj@nyc.pipeline.com) wrote:

>: I try to define a class which reads data from a paradox table.

>: I want to put this class in a unit file(not a form file).

>: It seems that delphi limits database access only to a form

>: file by drag and drop the data access control to the form.

>: Is there anyway to give database access to the class without

>: define to class in a form unit?

>

>

>Another option might be to create an object of one of the non-visual data

>classes, such as a TTable or a TQuery and calling that object's inherent

>methods to extract data.

Using TTable is the way to go.

But I ran into problem:

Unit Country;

...

var MYDatabase : TDatabase;

var TableCountry : TTable;

....

     MYDatabase := Session.OpenDataBase('DBDEMOS');

     TableCountry.DatabaseName := 'COUNTRY.DB';

<----GPF

     TableCountry.Open;

What is wrong?

--

Jin Mai        mwj@pipeline.com


Placing an Icon on a TBitBtn

#1007.UNS	From: waletz@eeserv.ee.umanitoba.ca (James Waletzky)

Hi there,

I am writing an app in which I want to have several bitmap buttons

(TBitBtn) each of which contain an icon of an executable program.

I have written the code to do this: the user selects an executable

file and the first icon from that .EXE file is placed on the button.

The problem is that the transparent portion of the icon is drawn as

garbage (random checkerboard-like pattern). Is there any way to

replace that transparent portion with the color of the button?

The code is provided below (for reference). In the example below,

there is a transparent portion of the icon around the "N" in the

Netscape icon. Any suggestions?

James.

----- icon to button code -----

{ TMainWindow is a class based on TForm and MainWindow is an instantiation

    of TMainWindow

  Button1 is on the form and is of type TBitBtn }

procedure TMainWindow.InitMainWindow(Sender: TObject);

var

  ButtonTBitmap: TBitmap;

  ButtonHBitmap: HBITMAP;

  ExecutableIcon: HICON;

  MemoryDC: HDC;

begin

  ExecutableIcon := ExtractIcon(HInstance, 'C:\WINSOCK\NETSCAPE\NETSCAPE.EXE',

0);

  MemoryDC := CreateCompatibleDC(MainWindow.Canvas.Handle);

  { NOTE: the 32x32 size could be replaced with the Width and Height

    fields from a TIcon object }

  ButtonHBitmap := CreateBitmap(32, 32, 1, 8, NIL);

  SelectObject(MemoryDC, ButtonHBitmap);

  DrawIcon(MemoryDC, 0, 0, ExecutableIcon);

  DeleteDC(MemoryDC);

  ButtonTBitmap := TBitmap.Create;

  ButtonTBitmap.Handle := ButtonHBitmap;

  Button1.Glyph := ButtonTBitmap;

  ButtonTBitmap.Free;

end;

{ Note that the created bitmap is 8 bits/pixel }

--

 James Waletzky                 \ "If builders built buildings the way

 University Of Manitoba         /  programmers wrote programs, the first

 umwaletz@ccu.umanitoba.ca      \  woodpecker that came along would

 waletz@ee.umanitoba.ca         /  destroy civilization." (Weinberg)


Grumpfish FTP Directory

#0.WEB	From Grumpfish

The Grumpfish FTP directory (ftp.teleport.com/vendors/mrgrump/) is

an excellent resource for Delphi developers. There are megabytes

of Delphi-related files available for your downloading pleasure,

including tons of freeware/shareware components, useful programming

examples, tips, Frequently Asked Questions, etcetera. Our FTP site

is updated with new and revised files on a weekly basis.

Anonymous login welcomed.


Various Web Sites

#00000000.WEB	From Kirk Wolak

These are some FTP/Web sites that I have found other people refer to.

FTP Sites:

        ftp://ftp.iconz.co.nz/pub/borland/usergroup/delphi/comps

        ftp://ftp.mhn.org/pub/delphi.faq

Web Sites:

        http://165.247.199.71/whatsnew/delphi.htm

        http://iconz.co.nz/commercial/Borland/Delphi/home.htm

        http://mailhost.net/~delphi

        http://sunsite.icm.edu.pl/archive/delphi/

        http://sunsite.icm.edu.pl/archive/delphi/freenew.html

        http://sunsite.icm.edu.pl/archive/delphi/freeware.html

        http://www.borland.com/Launch/NeedToKnow/FactSheet.html

        http://www.borland.com/Launch/NeedToKnow/QuInfo.html

        http://www.borland.com/Product/Lang/Delphi/Delphi.html

        http://www.borland.com/TechInfo/delphi/techdocs/faqs/index.html

        http://www.coriolis.com/bookstor/cgbsprog/devcust/devcust.htm

        http://www.coriolis.com/whatsnew/delphi.htm

        http://www.cs.vu.nl/~jprins/tp.html

        http://www.it.kth.se/~ao/DHC/

        http://www.mindspring.com/~cityzoo/buglist/buglist.html

        http://www.pcb.co.za/users/borising/cyborg.htm

        http://www.pennant.com/delphi/dconn/v1.1/n_resrc.html

        http://www.sai.com/

        http://www.teleport.com/~grump/


Distributing programs

#00000001.WEB	From KWolak@mail.cbf.com Wed Aug 23 10:27:40 1995

In article <113320703wnr@hardings.demon.co.uk> simon@hardings.demon.co.uk writes:

(I'm in the process of doing this right now, Simon. My experience may be

relevant to pothers, so I'll reply here).

>??Can I upload it to my Internet FTP server to spread it?

>        If so how do other people get it?

Many ftp and web sites accept uploads -- your local Demon site is one, for

example. They won't "spread" it though -- that's up to the people who

download it, try and and (hopefully) pass it on.  So one upload gets you one

site plus *potentially* others.

>??I programmed a database app. in Delphi using the BDE, can people

>download that from Borland instead of me uploading it to whta veer you

>suggest?

Good question, and I don't know the answer. I would NOT recommend uploading

the BDE with the app!

>??How can I post a 322kb file to a newsgroup? I have tried Uuencoding

>it but my mail program WinNews can not handle it.

DON'T post anything more than trivial code examples, and certainly not

uuencoded stuff (at least, until there is a delphi.binaries group).

OTOH, DO post an announcement (short, relevant) noting what sites you've

uploaded to. See my TCompress announcement posted yesterday for a halfway

house -- I posted it before I finished the ftp uploading so it misses that

vital info. (Covering my error: TCompress will shortly be available at:

http://iconz.co.nz/commercial/Borland/Delphi/home.htm

or ftp://ftp.iconz.co.nz/pub/borland/usergroup/delphi/comps

which in regular ftp form is: ftp.iconz.co.nz in  directory

/ftp/pub/borland/usergroup/delphi.

Also:  http://www.sai.com/, and at the UK Demon ftp site).

I'll also be hitting sunsite.icm.edu.pl and ftp.coriolis.com (the latter

being frequently mentioned via its url address of

http://165.247.199.71/whatsnew/delphi.htm).

I'll be trying many others I've collected, and will post a list of those

once I've confirmed they are accepting uploads of this nature.

>?? Has anyone else tried to spread a program in this way?

I've had six offers this morning from people who will upload it to "other"

places if I email it to them, which I've done (thanks, folks). So I'd say

that, in this connected world, the idea is VERY viable.

NB: Of course, all this isn't FREE -- it is costing us a modicum of mail (20

units mailed in response to requests so far), plus web/ftp connect charges.

But what the heck, TANSTAAFL.

cheers,

peter

--

==============================================================================

     Peter Hyde, South Pacific Information Services Ltd, Christchurch, NZ

       Makers of TCompress File and Database Compression Components


Multi-line Hints?

#00000002.WEB	From KWolak@mail.cbf.com Wed Aug 23 10:31:31 1995

>Does anyone know how you get Delphi to spread hints over multiple

>lines?

>The WebEdit HTML authoring tool does this, and it's written in Delphi

>so it is possible, but I can't find any reference to it in the Docs.

I have a component that allows multi-line hints.  It can be obtained

on http://www.teleport.com/~grump/ in their Delphi area.  The

filename should be: MBHINT11.ZIP.

-David Prothero

-International Technology Group

-Salem, Oregon


INSTALLATION UTILITY

#00000003.WEB	From KWolak@mail.cbf.com Fri Aug 25 09:19:47 1995

>Is there an installation utility that will set up a program group in

>windows for my application?

  There area several...  I am currently using a ShareWare version called

the Chief Installer Pro, written in Pascal (we must support our

bretheren).  It will set up your program group and even comes with an

uninstall.  Pretty good stuff Maynard.

Should be available on the net.  Let me see if I have the address...

Yup.  cheif@mep.com

Good Luck,

-Ed Salgado

 Eminent Domain Software


ReportSmith discussions

#00000004.WEB	From KWolak@mail.cbf.com Fri Aug 25 09:20:55 1995

In article <41jc7e$4u9@tulpi.interconnect.com.au> pwi@bha.oz.au writes:

>From: pwi@bha.oz.au

>Subject: ReportSmith discussions

>Date: Fri, 25 Aug 95 12:21:40 PDT

>Where do I post difficult questions for ReportSmith?

ReportShit itself is a difficult question - istn`t it?

>There seems to very

>little discussion of it in these groups.

Ok - let`s discuss about ReportShit

ReportShit has more bugs than features, the documentation is poor and

everybody who uses your applications can see that you are using this

stupid ReportShit.

And it is hungry! it needs a lot of space on your HD and of your RAM.

 -> So delete it and you`ll be happy.

Then get QuickReport V.093b it`s still beta but much better than this

ReportShit.

QuickReport V.93b is on http://sunsite.icm.edu.pl/archive/delphi/


Report Smith a nightmare !!!!!!!!!!

#00000006.WEB	From KWolak@mail.cbf.com Fri Aug 25 09:43:07 1995

In article <418uu9$pf2@forest.forest.nsw.gov.au> Matthew HOLMES <matthewh@ironbark.forests.nsw.gov.au> writes:

>From: Matthew HOLMES <matthewh@ironbark.forests.nsw.gov.au>

>Subject: Re: Report Smith a nightmare !!!!!!!!!!

it is!!!

>Date: 21 Aug 1995 03:35:37 GMT

>DProth@msn.com (David Prothero) wrote:

>>There is a fairly-decent shareware report writer specifically for

>>Delphi called QuickReport.  It couldn't get any more transparent, as

>>it is a set of components where you actually layout your report in

>>Delphi!  It works great for most general reporting needs, and it is

>>SMALL!  Compared to ReportSmith, though, anything is small.  I wrote

>>a simple report (one file, no totals, nothing fancy at all) and it

>>takes a year and a day to load it's stupid 'RS_RUNTIME' program.

yes this QuickReport is a great shareware tool. It is just under construction

but version 0.93b works fine and stable.

>This sounds interesting - could you tell me where I might find this product ?

here -> http://sunsite.icm.edu.pl/archive/delphi/

>Thanks

Report Shit is really a nigtmare !

Henry


WWW-Sites

#00000007.WEB	From KWolak@mail.cbf.com Mon Aug 28 14:45:42 1995

Try these:

     http://www.coriolis.com/whatsnew/delphi.htm

     http://www.it.kth.se/~ao/DHC/

     http://www.pennant.com/delphi/dconn/v1.1/n_resrc.html

     http://www.borland.com/Product/Lang/Delphi/Delphi.html

     http://www.borland.com/Launch/NeedToKnow/FactSheet.html

     http://www.borland.com/Launch/NeedToKnow/QuInfo.html

the first one is quite nice...


New WWW URL - Boris Ingram's Home Page

#00000008.WEB	From KWolak@mail.cbf.com Tue Aug 29 09:15:23 1995

Just a small announcement that Boris Ingram has finally got

his ass sufficiently into gear to get a WWW home page together.

All the stuff I've done is available there, plus some nice

Ducati Pic's !

All Welcome At

    http://www.pcb.co.za/users/borising/cyborg.htm

Come and say Hi

Boris Ingram, Cyborg Software

borising@iafrica.com


Delphi ftp sites ?

#00000009.WEB	From KWolak@mail.cbf.com Wed Aug 30 11:00:01 1995

Try http://sunsite.icm.edu.pl/archive/delphi/

Rgrds: Mats

--

////////////////////////////////////////////////////////////////////////

Argue for your limitations                      Mats Andersson

and you can be sure to keep them                Jakobstad

                Donald Shimoda                  FINLAND 967-7236 105

////////////////////////////////////////////////////////////////////////


Does a freeware\shareware zip compression algorithm Exist

#00000010.WEB	From KWolak@mail.cbf.com Fri Aug 25 09:35:27 1995

p.ewing@gmg.com.au (Peter Ewing) wrote:

>

> Does a freeware zip compression algorithm Exist or a sharewhere algorithm

> exist. Free would be better but if not could you please give me the location

> and cost.

I have seen ZipStudio which is a DLL-utility to compress/decompress both

interactivly and by programming API. I havent had time to try it myself...

The location is "src.doc.ic.ac.uk/prog/win/programr"

and the files are: zs20a.zip zs20b.zip and z255up.zip

It sounds like a wonderful utility...

/good luck


Intel 3DR

#00000011.WEB	From KWolak@mail.cbf.com Tue Sep 05 12:57:36 1995

In article <113797439wnr@shockwav.demon.co.uk>, Julian@shockwav.demon.co.uk

says...

>

>Somebody at the Devcon did a talk on multimedia that included a demo of

>Intel 3DR driven by a Delphi App. Does anybody have any details of where

>I can find a VCL or source that does the same? Unfortunately, I was a

>little sleepy after the night before :) and didn't get all the details

>at the time.

>

>--

>=======================================================================

>|  /\  | <Julian Bond> julian@shockwav.demon.co.uk | Ducati 900SS '93 |

>| /<>\ |                                           | MZ ETZ250    '80 |

>|/____\|   "Free World v2.0 now in wide beta."     | DoD# 65535       |

>=======================================================================

>

Check out http://sunsite.icm.edu.pl/archive/delphi/freeware.html.

--

Slawek Janicki

slawek@moose.scs.uiuc.edu


ANNOUNCE: Delphi Bug List

#00000012.WEB	From KWolak@mail.cbf.com Wed Sep 06 10:17:49 1995

The Delphi Bug List is now being maintained at the City Zoo WWW site.

Initially created and maintained by Brad Stowers, the list is migrating

to the City Zoo where Mark Johnson (me) believes he has enough time

to keep it current.  (yeah, right...)

An immediate addition to the Delphi Bug List is a World Wide Web form

for automated submission of new bugs.  So, if you have encountered

what you think may be a bug in Delphi and it is not in our list,

sumbit your critter to be added to our collection!

The Delphi Bug List can be found at the following URL:

    http://www.mindspring.com/~cityzoo/buglist/buglist.html

If you encounter any problems with these pages (or any other City Zoo

page), please inform me via e-mail (keeper@mindspring.com).  I appreciate

it!

Enjoy!

--Mark Johnson

______________________________________________________________________________

 Mark R. Johnson       _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_

 Atlanta, GA USA       _/  http://www.mindspring.com/~cityzoo/cityzoo.html  _/

 keeper@mindspring.com _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


Delphi Shareware CD-ROM

#00000013.WEB	From KWolak@mail.cbf.com Wed Jan 11 10:58:24 1995

EMS Professional Shareware is now shipping the 2nd (Aug'95)

edition of its Delphi shareware CD-ROM and diskette library,

with 258 PD/Shareware/Free ZIP files and a database describing

them. 4505 Buckhurst Ct., Olney MD 20832-1830, Voice:301-924-3594,

Fax:301-963-2708. ems@wdn.com http://www.wdn.com/ems


Is there a FAQ for delphi?

#00000014.WEB	From KWolak@mail.cbf.com Tue Sep 12 15:01:30 1995

Hi,

: Is there a FAQ for delphi?

  Yeah.. Try ftp://ftp.mhn.org/pub/delphi.faq !

Best Regards,

\/\/yàtt \/\/ong

+---------------------------------------------------------------------+

| Internet e-mail:                                                    |

| tfwong@yonet.org, tfwong@asiaonline.net, tfwong@iconet.hongkong.net |

+---------------------------------------------------------------------+


Delphi on TP Page

#00000015.WEB	From KWolak@mail.cbf.com Wed Sep 13 17:35:36 1995

Hi,

The links I have collected so far on Delphi are displayed in following

snapshot from http://www.cs.vu.nl/~jprins/tp.html   Subject/Delphi:

              -----------------------------------

================================================================

  DELPHI CLIENT/SERVER DEVELOPMENT

* WWW sites

       * Main page

       * CIUPKC's Delphi Page

       * Delphi WWW Page

       * Super Delphi Page

       * The Cool Delphi WWW Page

       * SynchroniciTech: Delphi-related services

       * Delphi Hackers Corner

       * A great Delphi Home page

* Information

       * First questions and answers

       * Introduction to Delphi

       * Delphi FAQ [local copy]

       * A listing of Delphi BUGS

       * How to compile to DOS exes with DCC

       * Technical support page

       * Delphi newsarticles from Borland

       * A Delphi reviewon the software forum

       * Delphi tips and tricks

       * Delphi Object Reference Manual

* FTP sites

       * Ice-floe FTP site

       * Salt Lake City Delphi FTP site

       * Borland FTP

       * Uwo, Canada

       * Hannover, Germany

* Components

       * A compression library for Delphi

       * Delphi Utility Library

       * A clockcomponent

       * A unit to get DOS environment variables

       * Drawing metaforms using Thandle

       * Wrapping text in TStringGrid

       * There are several Winsockpackages for Delphi

_________________________________________________________________

=================================================================

See ya, Jeroen


Q: any components ?

#00000016.WEB	From KWolak@mail.cbf.com Tue Oct 10 17:13:06 1995

SACO Software (sacosw@is.co.za) wrote:

: Is there a site out there anyware carry PD or ShareWare

: Delphi components ?

:

: Thx,

:

:

: Ken - sacosw@is.co.za

        The BEST WWW page about Delphi is the Super page.

        http://sunsite.icm.edu.pl/archive/delphi/freenew.html

        Happy surfing...

--

*****************************************************************

Joe LeVasseur lvasseur@tiac.net vasseur@nai.net

   Linux geek at large! Well, not THAT large....

*****************************************************************


ANNOUNCE:   New Delphi WWW Site

#00000017.WEB	From KWolak@mail.cbf.com Tue Oct 10 17:16:51 1995

                    Delphi Developer's Library:

Visit our new site at  http://mailhost.net/~delphi

We'll be adding new components/information from time to time.

Cheers,

Delphi Developer's Library


Is there a Delphi knowledge base???

#00000018.WEB	From KWolak@mail.cbf.com Thu Oct 19 01:10:10 1995

by101av@sun1.lrz-muenchen.de () wrote:

>

>Hello,

>I want to know if there is a knowledge base (like for Visual Basic) or

>equ. for Delphi ???

>

>Guenter Kaiser

>kaiser@fh-rosenheim.de

Even better!

There is a "freeware" site with components to solve just about

any problem:

http://sunsite.icm.edu.pl/archive/delphi/freeware.html

Hope this helps,

Arthur Hoornweg


Delphi FAQ

#00000020.WEB	From KWolak@mail.cbf.com Thu Oct 26 21:44:16 1995

There is a good Delphi faq at the Borland server:


Component Development Book

#00000021.WEB	From KWolak@mail.cbf.com Thu Nov 02 16:48:17 1995

jkeller@mail.coast.net (Joe Keller) wrote:

>Does anybody know of some good third party books on Delphi component

>development (if any)?

The Coriolis Group, which published the Delphi Exlporer will be

publishing a book called Developing Custom Delphi Components which is

supposed to come out this month.  For more info, check out this web

page:

http://www.coriolis.com/bookstor/cgbsprog/devcust/devcust.htm

HTH,

Bert


Grumpfish Web Site

#01.WEB	From Grumpfish

The Grumpfish World-Wide Web site

(http://www.teleport.com/~grump) is an excellent

resource for Delphi developers. There are megabytes

of Delphi-related files available for your downloading

pleasure, including tons of freeware/shareware components,

useful programming examples, tips, Frequently Asked Questions,

etcetera. Unlike some web sites, ours is far from stagnant...

new and updated files are posted at least once a week. We

have also put a considerable amount of thought into providing

interesting and useful links to other web sites.

We invite you to visit!


Compression with Delphi

#1000.WEB	From: cifsab@inet.uni-c.dk (Anders Bjerre)

Pten 13 (pten13@aol.com) wrote:

: Does anyone know of a compression library that I can use with Delphi?  I

: want to add compression to some encryption software, but I can't find

: anything that will work.

: I have tried to use MarshallSoft's LZW4P and LZW4W, but they don't work.

: Steve

There is some compression stuff in the last SWAG set (Feb. 95), which is

accessible (at least) on garbo and probably quite a few other places.

(I don't have my Swag files at the place I use the net so I can't say it

more specifically than this - sorry!)

Happy coding

Anders Bjerre, Copenhagen Institute for Futures Studies


Expression Evaluator Source?

#1001.WEB	From: awax@dep071.ennet.krasnoyarsk.su

In article <3lca1s$mvf@mark.ucdavis.edu>, jmokeefe@nachos.engr.ucdavis.edu

(John Michael

Okeefe) writes:

>

>

>

>       I'm looking for Pascal, Turbo Pascal, or Object Pascal source

>code for a mathmatical expression evaluator. If you know where I can find

>a FTP site for this let me know. I'm also looking for source code for

>mathmatical and statistical functions. Thanks for any help provided.

>

>

   Dear Sir !

   Try this mailserver : (in Russia)

   mailserv@alma-ata.su

   AWAX.


What are some good books about Delphi?

#00000000.MAG	From FAQ

   Delphi for Dummies, by Neil Rubenking, is the only one that has been widely

   circulated to general bookstores, and as usual with a For Dummies books,

   contains quite a bit of good information among the silly chapter headings

   and excitable prose. Other books that are either in print or on their way

   to print are:

   The Delphi Programmer Explorer, Duntemann/Mischel/Taylor

   Teach Yourself Delphi, Devra Hall

   Delphi by Example, Blake Watson

   Using Delphi, Special Edition, Namir Shammas

   Delphi Developer's Guide, XavierPacheco/Steve Teixeira

   Mastering Delphi, Charlie Calvert

   Teach Yourself Delphi in 21-Days, Andrew Wozniewicz

   Delphi How-To, Gary Frerking

   Developing Windows Applications Using Delphi, Paul Penrod

   Instant Delphi, Dave Jewell

   Delphi Nuts and Bolts, Gary Cornell and Troy Strain

   Software Engineering with Delphi, Edward C. Webber, J. Neal Ford,

   Special Edition Using Delphi, John Matcho, Mark Andrew, et al

   Developing Client/Server Applications with Delphi, Killen/Todd

   Delphi Programming Unleashed, Charlie Calvert

   Mastering Delphi, Tom Swan

   Mastering Delphi, Marco Cantu


Delphi Unleashed

#01.MAG	From ZAC Catalog, Delphi Only Tools

Author:   Charlie Calvert

Audience: Intermediate - Advanced

Pages:    976

Diskette: CD (all source code from the book)

Charlie Calvert is a Technical Support Engineer for Borland International.

He assumes that you have programming experience and seeks to help you get

the most out of Delphi.  Your code will become more effective and streamlined

as you learn the advanced techniques from an experienced Pascal programmer

from Borland.  Professional tips with actual code examples combine to give

you many real-world examples including a database inventory application and

a Windows game!  The technical accuracy of this book was verified by

members of Borland's Technical Support staff before it was published.

SOURCE: ZAC Catalog, Delphi Only Tools

ZAC Price: $44

Prod #:    4025-01325

To Order: 1-800-GO DELPHI (1-800-463-3574)


Delphi By Example

#02.MAG	From ZAC Catalog, Delphi Only Tools

Author:   Blake Watson

Audience: New Programmers

Pages:    650

Diskette: None

Blake Watson does it again with his Delphi By Example.  Known for his

articles in PC Techniques and VBX/OCX Developer, as well as his OS/2 Warp

Programming for Dummies to me, this one is aimed squarely at newbies with

little or no development experience in any language!

Each chapter is broken down into bite-sized chunks so that nothing is

misunderstood.  Plenty of source code examples are there to further

illustrate the chapter's concepts.

The book starts out with the basic concepts of programming along with

a clear explanation of the tools that come with Delphi.  Next, the Pascal

language itself is explored alongwith how to build an application in

Delphi.  This is the book to read if you are new to programming and are

getting started with Delphi.

SOURCE: ZAC Catalog, Delphi Only Tools

ZAC Price: $29

Prod #:    4030-01325

To Order: 1-800-GO DELPHI (1-800-463-3574)


Instant Delphi Programming

#03.MAG	From ZAC Catalog, Delphi Only Tools

Author:   Dave Jewell

Audience: Beginner - Intermediate

Pages:    446

Diskette: 3.5" with source code from book

If you're looking for a "Quick Learn," or moving over to Delphi from Pascal

or Visual Basic, then this is a great book.  Dave Jewell takes you on a

whirlwind tour of the benefits and capabilities of Delphi and then gets into

the fundamentals of designing and developing a program using the IDE.  There

are sections on debugging and customizing Delphi as well.  Advanced sections

on Database access and creating your own components make for a good learning

experience.  An especially great section is an overview of Delphi written for

Pascal and Visual Basic developers.  This section gives you a good idea of

the similarities and differences that help make your conversion to Delphi

less painful.

SOURCE: ZAC Catalog, Delphi Only Tools

ZAC Price: $24

Prod #:    4040-01325

To Order: 1-800-GO DELPHI (1-800-463-3574)


The Tao Of Objects

#04.MAG	From ZAC Catalog, Delphi Only Tools

Author:   Gary Entsminger

Audience: Every programmer in the world!

Pages:    241

Diskette: None

This book is a guide to objects, object-based software development and

object-oriented programming.  It's written for software developers,

programmers, and anyone who knows at least a little about programming and

wants to understand why objects are hot and how they work.  In particular,

Delphi, C++, Visual Basic and xBase programmers will learn how to rethink

their programs using objects.

The Tao of Objects is a friendly, hands-on book that emphasizes the key

advantages of programming with objects.  The examples in the book are

general enough to be of interest to anyone -- and they're fun.  I thought I

knew "enough" about objects until I studied this book.  If you make a

living developing software then you should get a copy.

SOURCE: ZAC Catalog, Delphi Only Tools

ZAC Price: $27

Prod #:    4028-01325

To Order: 1-800-GO DELPHI (1-800-463-3574)


Delphi Programming Explorer

#05.MAG	From ZAC Catalog, Delphi Only Tools

Author:   Jeff Duntemann, Jim Mischel and Don Taylor

Audience: Beginner - Intermediate

Pages:    626

Diskette: 3.5" with source code from book

The introduction to this book reads: "The idea was to put together a book

that gets a new user up and running in as little time as possible -- and

makes it a wild good time!"  Well, they certainly did that.  While the

style is light and humorous, the concepts are serious and useful.  They

even get into converting Visual Basic to Delphi and handle it quite well.

You'll learn about designing forms, using objects and performing math while

building a mortgage calculator.  Although a hefty 626 pages, it's an easy

read and the included source code diskette eliminates the typing!

SOURCE: ZAC Catalog, Delphi Only Tools

ZAC Price: $39

Prod #:    4035-01325

To Order: 1-800-GO DELPHI (1-800-463-3574)


Delphi Programming For Dummies

#06.MAG	From ZAC Catalog, Delphi Only Tools

Author:   Neil J. Rubenking

Audience: Beginner - Intermediate

Pages:    376

Diskette: None

Don't let the title insult you.  Delphi Programming For Dummies is a

storehouse of knowledge.  From the very first page, Neil takes you on a

guided tour of Delphi and all of its power.  It's easy to read, sprinkled

with very funny cartoons and succeeds in tricking you into learning by

hiding knowledge as entertainment.  Filled with how-to's (and how-not-to's),

tips, trickes and code examples, Delphi For Dummies will have you developing

real stuff real quick.  If you hate to read, but need to learn, this is the

book for you.

SOURCE: ZAC Catalog, Delphi Only Tools

ZAC Price: $19

Prod #:    4020-01325

To Order: 1-800-GO DELPHI (1-800-463-3574)


Delphi Developer's Guide

#07.MAG	From ZAC Catalog, Delphi Only Tools

Author:   Xavier Pacheco and Steve Teixeira

Audience: Intermediate - Advanced

Pages:    868

Diskette: CD

Ther's almost 900 pages of Insider's knowledge in this book.  You'll be amazed

at how thoroughly Borland insiders Xavier Pacheco and Steve Teixeira provide

experienced Pascal and Delphi developers a solutions-oriented approach to

RAD concepts with Delphi.  You can fire up the included CD-ROM with all of its

examples, sample applications and free VCL Components.

Xavier's experiance as a Consulting Engineer and Steve's experience as Senior

Engineer in Borland's Technical Support Department really shows through.  It's

like you're a partof Delphi's design team.  The section on moving to Pascal

is a "must read" if you're coming to Delphi from another language.

SOURCE: ZAC Catalog, Delphi Only Tools

ZAC Price: $49

Prod #:    4023-01325

To Order: 1-800-GO DELPHI (1-800-463-3574)


Delphi: A Developer's Guide

#08.MAG	From ZAC Catalog, Delphi Only Tools

Author:   Bill Todd and Vince Kellen

Audience: Intermediate - Advanced

Pages:    797

Diskette: CD

Explore Delphi from the ground up with almost 800 pages of wisdom from authors

Bill Todd and Vince Dellen.  There's a special section on using Delphi Client

Server and a CD-ROM with all the sample code, a set of third party VCLs and

the finished programs so you can spend less time becoming an expert.

Detailed examples cover topics ranging from flat file I/O to data integrity

and security.  You'll learn how to build full featured database programs that

stretch Delphi to the limit.

There's plenty of detailed that cover using Delphi's database controls, the

Borland Database Engine (BDE), Interbase and SQL Server.  There's a good

section on OOP development and techniques and TQuery objects.

This book is great for intermediate to advanced developers and thos of you

planning to take the Client/Server plunge.

SOURCE: ZAC Catalog, Delphi Only Tools

ZAC Price: $44

Prod #:    4038-01325

To Order: 1-800-GO DELPHI (1-800-463-3574)


Delphi language reference

#1000.MAG	From: Steve Teixeira <steixeir@borland.com>

keving@primenet.com (Kevin Goldstein) wrote:

>

> I can't seem to find anything resembling a Delphi language manual, either

> printed, in the on-line help, or as part of the Acrobat manuals-on-line

docs.

> The only thing on the language is in the user guide, which isn't complete.

> The reference manual must exist somewhere, I'm sure I'm just overlooking it;

> anyone know where it is???

>

> -Kevin

Open the online help (DELPHI.HLP), and select either the "Object Pascal

Language" hotlink or the "Delphi Visual Component Library" hotlink.

        -Steve Teixeira

         steixeir@borland.com

From: jpmccreesh@pines.demon.co.uk ("John P.McCreesh")

In article <pacsoftD54wKL.640@netcom.com>

           pacsoft@netcom.com "Wilhelm Sarasalo" writes:

> I don't know how to cut and paste from the examples though  :(

Try Edit Copy ... Edit Paste  :-)  It does work, and is really useful to

Pascal newbies like me who can't remember where all the damn semi-colons

go (or don't)

John

+---------------------+------------------------------------------------------+

 John P.McCreesh      |  Internet: jpmccreesh@pines.demon.co.uk

 Forbo-Lancaster Ltd. |  X.400:    c=GB,a=CWMAIL,p=FORBO,g=John,s=McCreesh

 Lancaster, England   |  Voice:    +44 (0) 1524 65222  Fax: +44 (0) 524 61638


Delphi Documentation

#1001.MAG	From: dintersimone@wpo.borland.com (David Intersimone)

In article <3k01tm$a5q@flood.xnet.com>, maestro@flood.xnet.com (Craig Wells)

says:

>

>Well I haven't purchased Delphi yet (trying to decide). One thing I have

>noticed that is quite consistent in the postings is the fact that Borland

>made a fantastic product but skimped on the documentation!  Not a very

>good idea for a company that is "betting the company" on Delphi.  They

>want persuade Visual Basic programmers to defect but it may be a hard

>sell with poor and incomplete documentation.

We are not betting the company on Delphi or any other one product. Delphi

is selling very nicely - thanks everyone.  our other products are doing

well too.

Check out our WWW.BORLAND.COM web site for more articles and delphi

information.  books will be coming out "real soon now" filled with

all the information you'll ever need abou Delphi.

David I, Borland

From: Steve Teixeira <steixeir@borland.com>

efp@mindspring.com (Eric F. Palmer) wrote:

>

> I'm sorry but Steve I do think you are wrong.  Now don't get me wrong, I

love

> the product but there are so many features (compared to VB) that it requires

a

> lot more documentation.  In addition, I'm new to Pascal and when I adopt a

new

> language I like to read the language manual fron to back to make sure I

> understand and use the language to its fullest.  I take it with me and read

it

> everywhere (I do mean everywhere) <grin>.

>

> But, no language manual is included.  Making sure you read all of the

> language ref. on-line is an act of click click and make sure you back trace

so

> that you can read it all.  I like on-line docs for quick answers but there

is

> nothing like a good manual that you can read anywhere to increase ones'

> productivity.

>

> Yes I did order the two extra docs. but I think this should have been

included

> with the product and yes I would pay more.  Please - if you work for Borland

> you will listen to the customers.  Don't be defensive.  We may stretch the

> truth but there is an essence of value in what we say.

>

> Many good companies  with good products have fallen on hard times when they

> fail to listen to the customer.

>

Eric,

Thanks for your well-thought feedback.  We realize that it was probably a bad

decision not to have the supplemental documentation available at Delphi ship-

time. Additionally, we realize that we should have included the VCL and Object

Pascal references in Acrobat format.  We are definately working to rectify

these

problems, and we *really do* appreciate all the input we've gotten on this

point.

Delphi has been customer-driven from the get-go, and we're not about to stop

now.

        -Steve Teixeira

         Borland International Technical Support

         steixeir@borland.com

From: Steve Teixeira <steixeir@borland.com>

hans.busk@dkb.dk (HANS BUSK) wrote:

>

> ST> time. Additionally, we realize that we should have included the VCL

> ST> and Object Pascal references in Acrobat format.  We are definately

>

> Please. The Acrobat format is terrible! I would appreciate very much if

> the document could be made in an additional format, even ASCII looks

> better to me, but a windows .HLP file format seems to be relevant

>

> The problems with Acrobat? It is extremely slow, and I don't know how

> to make a hard copy on a non-proscript printer. Among other things.

>

> Delphi is very good though!

>

The VCL and Object Pascal references *are* in the Delphi help file. Just

select Help|Contects and select the "Visual Component Library" or "Object

Pascal" reference hotlinks.

        -Steve Teixeira

         steixeir@borland.com

From: Steve Teixeira <steixeir@borland.com>

joe_willcoxson@wiltel.com wrote:

>

>

> Borland I hope you are listening!

>

> Lot's of people have been posting gripes about the Borland

> documentation, and rightly so!  IMHO the documentation for

> Delphi is definitely lacking.  To get what should have been

> included in the package costs an extra $140:  the VCL

> source code and the *extra* or *supplementary*

> documentation.  The way they are marketting these *extras*

> seems like a micro$oft ploy.  Please sell a complete

> product and stop all these extra come-ons.

Both the VCL and Object Pascal references are *included* in Delphi as part

of Delphi's main help file.  For those whole prefer printed documentation,

that is available at an extra cost, which helps us keep the cost lower for

those who would rather use the winhelp files.

We have admitted that not including the Acrobat versions of the VCL and

Object Pascal references on the CD was a mistake, and so was not having the

printed docs available as soon as Delphi shipped.  For those things, we

apologize.

Not everyone wants the VCL source, and not everyone wants to pay for it.

Yes, we could have thrown everything in the box and introduced Delphi at

a much higher price, but by not including these "extras," you can buy Delphi

on the street for *well* less than $200, which beleive is an outstanding

value.

        -Steve Teixeira

         steixeir@borland.com


WWW-based magazine "The Delphi Connection"

#1002.MAG	From: gwitty@newpop.sccsi.com (Dan Luther)

Fellow Delphi Enthusiasts,

Soon, there will be a new WWW based magazine devoted to Delphi

called "The Delphi Connection", and we want you to play an

active part in both its creation and existence.

This is going to be an adventure on several fronts. To begin

with, this is our first foray into web based publishing.  I

just want to make that clear up front. Naturally, this project

will evolve over time. And I want you to know that mistakes

will be made, but I would like to refer to these as "learning

experiences".

Okay, so why a www-based magazine for Delphi, and what are our

goals? Well, we were both bowled over by Delphi. We believe

this truly represents the future of OO based programming. Our

goal is to be the definitive source for Delphi-related

information on the internet, and to provide a periodical that

everyone can access. Now, that's a fairly sizeable goal to be

sure, but with the help of the internet community at large, I

think it is an attainable goal.

Content is going to be provided by you! If you've ever had an

interest in having your work published, but were put off by the

process by which printed material is handled, or never even

gave it a second thought, well, here's your opportunity.

"The Delphi Connection" will have feature articles covering any

aspect of Delphi you feel like covering. We intend to have

product reviews, book reviews, a tips section, and a section

devoted to product advertisers, consultants, and links to other

neat delphi-related stuff on the net.

To submit articles, just e-mail them to me, Dan Luther

(gwitty@sccsi.com), or Nick Nafpliotis (nafpliot@mcs.com).

Currently, we are looking for submissions for articles, tips,

and advertisements.

This is a completely non-profit venture. In other words, we are

not charging for advertising space. So if you have a

delphi-related product you would like to have reviewed, or

already have a review by another source and have permission to

reprint, please do so.

One major goal in this magazine is to remain as objective as

possible, therefore comparitive reviews at this point are just

not going to happen.

Another point I think needs to be stressed is the distribution

aspect of the magazine articles and reviews. All articles will be

placed in the public domain, just by the very nature of the

magazine it has to be that way. We will make our best effort

to protect all intellectual property, and all copyrights will

be noted where applicable. We do ask that if you submit an

article, that you also provide a .ZIP file containing all

necessary code to recreate the examples where necessary.

Authors: If you have a tool or book you would like to have

reviewed in "The Delphi Connection", please e-mail me or Nick.

Well, that's about as good a place as any to start. We also

welcome all comments, advice and tips, so if you have that, fork

it over! :)

     (o) (o)         Dan Luther            Black Gold BBS

--oOO--(_)--OOo--------------------------------------------------------

           INTERNET: dan.luther@bgbbs.com  Oklahoma's Biggest and Best!

               FIDO: 1:170/309             (918) 272-7779

                            It's sad to live in a society where an entire

                          family can be torn apart by something as simple

                          as a pack of wild dogs...


Delphi Seminars Series

Delphi Seminar Series

Grumpfish is proud to be a partner in the Delphi Seminar Series. These seminars are being held in major North American metropolitan areas through 1996.

We pride ourselves on providing the best in Delphi education at a fair price. Our instructors have trained a combined total of over a thousand developers and do their absolute utmost to answer your questions.

Attendees receive printed course materials and examples on diskette that will serve as a reference long after the seminar is over. Also, each attendee receives a complimentary trial subscription to the Delphi Aquarium, the disk-based technical journal for Delphi developers.

Each seminar is three days long. A brief synopsis of our curriculum follows.

Day 1: "Introduction to Delphi"

•	Essential elements

•	Integrated Development Environment

•	Forms and Controls

•	Visual Component Library guided tour

•	Developing sample applications with the VCL

Days 2-3: "Delphi Fundamentals"

•	MDI/SDI overview

•	Object Pascal

•	Debugging

•	Objects and Components

•	Generating Reports

•	Developing Database Applications

•	Client/Server overview

Students receive a comprehensive printed reference manual; tons of examples on diskette; and over 10 megabytes of various Delphi resources (tips, VCL and Object Pascal references, freeware and shareware ecomponents).

Also available are "Delphi Advanced and Client/Server" seminars, which will last three days. Topics covered during this seminar include:

Advanced Pascal Techniques

•	Elements of Object Pascal

•	Memory Management

•	Object Orientation

Advanced Development Topics

•	Events and Messages

•	Message Handlers

•	.INI File Management

•	Writing DLLs

•	Using DLLs with Delphi

•	WinSight/WinSpector

Creating Custom Components

•	Timer Panel

•	Statusbar

•	INI File Manager

•	More Components TBD

Advanced Database Techniques

•	Data Relationships

•	Data Validation

•	SQL

•	Referential Integrity

Advanced Form Design

•	MS-Windows GUI Standards

•	Combining components

•	Working with specialized components

•	Owner-draw controls

Multimedia and Graphics

Exception Handling

Anatomy of a Delphi Application

To register for the site nearest you, contact ZAC Catalog at 1-800-GO-DELPHI.

Related Topics:

Comments From Our Attendees

Intro/Fundamentals Seminar Schedule

Advanced Seminar Schedule


Comments From Our Attendees

"The instructor was very effective and responsive to questions" — Ronald  S. San Jose

"This seminar is a great way to step through many parts of Delphi with Q&A  as you go" — Gary Campbell

"The instructor had excellent knowledge of Delphi. The seminar was very fast and comprehensive" — Jose Suarez

"I feel much more confident with Delphi as a result of this course" — Edward Talbot

"I liked the fact that we got real-world examples to take home. At first I  wasn't sure because the class wasn't hands-on, but the Grumpfish  interactive lecture style was better" — Gloria Bias

"The course touched upon a lot of topics, and the samples on disk provide a good reference"— Maurice Whetstone

"I enjoyed the instructor's expertise and the way that the subject was  presented. This is a good way to keep current" — Wade Gillon

"Very informative and easy to follow"— Paul Geyer

"I enjoyed the real examples along with the explanations. Any question, no matter how elementary or advanced, was addressed. The instructor either answered questions, or when unsure of the answer, did research to provide an answer the following day" - Jim Fishwick

"Building an application during the seminar is a great teaching method" — Kevin Carbiener

"Excellent tutor... one of the best seminars I have attended" — Paul  Pattison

"I wish I had attended this seminar months ago"—Robert Roeth

"An excellent three days... the instructor was really on top of Delphi"—Robert Foley

"The instructor was willing to help individuals with their problems"—Larry Pint

"The instructor was very knowledgeable"—Fred Aayes

"Good material and presentation"—Frank Font

"I liked the exchange between the instructor and the attendees. You can't get that from a book!"—Quincy Franklin


Intro/Fundamentals Seminar Schedule

January 10-12	Charlotte

January 10-12	Los Angeles

January 17-19	Chicago

January 24-26 	Salt Lake City

January 24-26 	Washington DC

January 29-31	Houston

February 5-7	Detroit

February 7-9	San Francisco

February 14-16	Portland

February 14-16	Dallas

February 21-23	New York

February 28-3/1	Indianapolis

February 28-3/1	Seattle

March 4-6	Orlando

March 6-8	Atlanta

March 13-15	Philadelphia

March 18-20	Phoenix

March 20-22	Boston

March 27-29	Minneapolis

April 3-5	Columbus

April 3-5	Denver

April 10-12	Los Angeles

April 10-12	Tampa

April 17-19	Chicago

April 24-26	Washington DC

May 1-3	Kansas City

May 6-8	Miami

May 8-10	Dallas

May 15-17 	San Francisco

May 22-24	New York

May 29-31 	Houston

June 3-5	Indianapolis

June 5-7	Atlanta

June 10-12	Detroit

June 12-14	Philadelphia

June 17-19	Albuquerque

June 19-21	Boston

June 26-28 	Seattle


Advanced Seminar Schedule

January 17-19	Los Angeles

January 22-24 	Chicago

January 29-31	Washington DC

February 14-16	San Francisco

February 21-23	Dallas

February 26-28	New York

March 11-13	Atlanta

March 20-22	Philadelphia

March 25-27	Boston

April 15-17	Los Angeles

April 22-24	Chicago

May 1-3	Washington DC

May 15-17	Dallas

May 20-24	San Francisco

May 29-31 	New York

June 10-12	Atlanta

June 19-21 	Philadelphia

June 24-26	Boston


How to Send Articles to The DKBS

To send articles, just send Email to DelphiKBS@mail.cbf.com

The Subject line will be the articles title (e.g. How to Send Articles to The DKBS).

The mail message should be formatted as follows:

First Line: Topic: <TopicName|TopicAbbreviation>

Second Line: Keywords: Each, Word, with a comma separating, them

Third Line: Blank

After That: The text of the message

Example:

Topic: OOP

Keywords: .Create, Creating Objects, GPF Using Object

>I have a TList (MyList) that gives me a GPF whenever I use it.  What am I doing >wrong?

You need to .Create the Tlist first, as in:

Var

  MyList: Tlist;

Begin

  MyList := TList.Create;

  {Now you can use MyList safely}

End;


Topic Names & Abbreviations

The Topics Everyone Can Post to!

Section Name	Section Abbreviation	Description

FAQs	FAQ	Frequently Asked Questions

Misc/Tips	Tip	Tips (this is the default)

Tips

Misc

IDE	IDE	Delphi's Environment

BDE	BDE	General Database Issues

Client/Server	CS	CS Specific Issues

OOP	OOP	Object Oriented Issues

C/C++	C	Q&A for C Programmers

Visual Basic	VB	VB Related Information

Any section marked with an * can only be modified my a monitor.  Any section marked with ** can only be modified by myself.  I am sure you can guess why.


The Developers of the Delphi KBS

My personal thanks to the following for their help!

This Knowledge Base is compiled from public sources of information.  The initial idea to automate this belongs to Kirk Wolak (myself).  But I had a lot of help along the way...  Specifically the following people who volunteered their time and energy.  For which, I am very appreciative.  Most of the people listed below are at a level where 80-90% of the information in this Knowledge Base is of little use, but they volunteered because of their desire to make the lives of others easier.  We just hope everyone else finds it useful.

Finally, let me mention that Ken Masters has my utmost appreciation for his incredible contribution to this cause.  He has spent many hours editing and formatting much of this initial file.  For that, I am eternally grateful.  It is just another example of how far good people will go to help you do something nice!

Ed Ayers

Marko Bracic

Todd Fast

Greg lief

Ken Masters

Bengt Richter

Kirk Wolak


Lloyd, and Lloyds Help File

Credit here given for the use of Lloyds Help File (ldelphi.hlp).  Currently we have utilized this help file only for the Run-Time Errors, and the Table of BDE errors.  But with Lloyd's help and support, we hope to include much more.


Mike Orriss, Dtopics

Mike created a program and database called Dtopics.  You can find it on the Net as DTopicsP.zip (the program) and DTopicsD.zip (The data).

At this point, we have not utilized this resource because we have been unable to get permission from Mike.  Of course, this is not Mikes fault, he is waiting to hear from CompuServe if it is OK, because his information came from the Delphi Forum on CompuServe.


ZAC Catalog, Delphi only Tools

Thanks to ZAC Catalog for letting us use their Book Reviews, and for their promised help to spread the word about this Knowledge Base. I hope to have them help out by supplying the Seminar Information as well.

Nonetheless, remember 1-800-GO-DELPHI for your Delphi needs!


Glossary of Terms

monitor

ldelphi.hlp

http://www.teleport.com/~grump

ftp.teleport.com/vendors/mrgrump/


monitor

A volunteer who has been granted supervisor type access to the Knowledge Base.  They can delete/modify postings, as well as post to * sections.


ldelphi.hlp

Lloyds Help File.  This is an excellent resource.  Lloyd works for Borland, and puts the answers to some very interesting questions in this help file.  Full of useful information.


http://www.teleport.com/~grump

The Grumpfish World-Wide Web site is an excellent resource for Delphi developers. There are megabytes of Delphi-related files available for your downloading pleasure, including tons of freeware/shareware components, useful programming examples, tips, Frequently Asked Questions, etcetera. Unlike some web sites, ours is far from stagnant... new and updated files are posted at least once a week. We have also put a considerable amount of thought into providing interesting and useful links to other web sites. We invite you to visit!


ftp.teleport.com/vendors/mrgrump/

The Grumpfish FTP directory is an excellent resource for Delphi developers. There are megabytes of Delphi-related files available for your downloading pleasure, including tons of freeware/shareware components, useful programming examples, tips, Frequently Asked Questions, etcetera. Our FTP site is updated with new and revised files on a weekly basis. Anonymous login welcomed.